2012-09-14 83 views
6

我一直在嘗試使用WCF創建一個相對簡單的自託管RESTful服務,但我想添加自定義身份驗證。爲此,我試圖覆蓋UserNamePasswordValidator。不幸的是,儘管這被稱爲驗證用戶名/密碼組合,但如果用戶名/密碼沒有通過,服務器會返回403 Forbidden,而不是像我期望的那樣返回401 Unauthorized。這會造成很大的問題,因爲如果用戶第一次驗證失敗,他們將不會再次輸入憑據,除非他們重新啓動瀏覽器。那麼,我做錯了什麼?爲什麼我的自託管WCF服務返回403 Forbidden,而不是401 Unauthorized?

這是我到目前爲止有:

(實際ServiceContract包含返回字符串的一個方法)我已經採取了這一other, similar question的音符

class Program 
{ 
    static void Main(string[] args) 
    { 
     WebServiceHost host = null; 
     try 
     { 
      host = new WebServiceHost(typeof (MyService)); 
      const string uri = "http://127.0.0.1/MyService"; 
      var wb = new WebHttpBinding 
          { 
           Security = 
            { 
             Mode = WebHttpSecurityMode.TransportCredentialOnly, 
             Transport = {ClientCredentialType = HttpClientCredentialType.Basic} 
            } 
          }; 
      var ep = host.AddServiceEndpoint(typeof (IMyService), wb, uri); 
      host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; 
      host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new PasswordValidator(); 
      host.Open(); 

      Console.WriteLine("Press any key to terminate"); 
      Console.ReadKey(); 
     } 
     finally 
     { 
      if (host != null) host.Close(); 
     } 
    } 
} 

public class PasswordValidator : UserNamePasswordValidator 
{ 
    public override void Validate(string userName, string password) 
    { 
     if (null == userName || null == password) 
      throw new ArgumentNullException(); 

     if (userName == "Test" && password == "Password") return; 
     throw new WebFaultException(HttpStatusCode.Unauthorized); 
    } 
} 

,但沒有的張貼在那裏的答案實際上工作我希望問題的更完整定義版本能夠引發更好的反應。據

public override void Validate(string userName, string password) 
{ 
    if (null == userName || null == password)    
     throw new ArgumentNullException(); 
    if (userName == "Test" || password == "Password") return; 

    WebFaultException rejectEx = new WebFaultException(HttpStatusCode.Unauthorized); 
    rejectEx.Data.Add("HttpStatusCode", rejectEx.StatusCode); 
    throw rejectEx; 
} 

,因爲我知道這是一個無證技術的WCF堆棧如何在內部管理例外,它們依賴於:

+1

這可能有助於http://stackoverflow.com/questions/2198560/self-hosted-wcf-rest-service-and-basic-authentication – Alex

+0

它不完全有幫助,因爲這樣,但它確實提供道義上的支持並解釋:) – adhocgeek

+0

其實,我收回,我沒有看得太遠,看到有一個解決方案在那裏,是相同的發佈和接受這個問題。 – adhocgeek

回答

7

試試這個。應該有一個記錄的方式,但我還沒有找到一個。

+0

你是從哪裏發現的? :)它的工作原理,但它讓我思考我是否真的想現在使用WCF ... – adhocgeek

+0

我使用Reflector查看了WCF代碼。 –