2012-09-14 35 views
6

Tôi đã cố tạo một dịch vụ RESTful tự lưu trữ tương đối đơn giản với WCF, nhưng tôi muốn thêm xác thực tùy chỉnh. Để kết thúc, tôi đã cố gắng ghi đè số UserNamePasswordValidator. Thật không may, mặc dù điều này đang được gọi để xác nhận hợp lệ tên người dùng/mật khẩu kết hợp, nếu tên người dùng/mật khẩu không vượt qua, máy chủ trả về 403 Forbidden, thay vì 401 Unauthorized, như tôi mong đợi. Điều này sẽ gây ra một vấn đề lớn bởi vì nếu người dùng không xác thực lần đầu tiên, họ sẽ không được nhắc nhập lại thông tin đăng nhập trừ khi họ khởi động lại trình duyệt. Vì vậy, tôi đang làm gì sai?Tại sao dịch vụ WCF tự lưu trữ của tôi trả lại 403 Cấm, thay vì 401 Không được phép?

Đây là những gì tôi có cho đến nay:

(Các thực tế ServiceContract chứa một phương thức duy nhất mà trả về một chuỗi)

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); 
    } 
} 

Tôi đã từng lưu ý của other, similar question này, nhưng không ai trong số các câu trả lời được đăng ở đó thực sự hoạt động. Tôi hy vọng một phiên bản được xác định đầy đủ hơn của câu hỏi sẽ gợi ra một số câu trả lời tốt hơn.

+1

Điều này có thể giúp http://stackoverflow.com/questions/2198560/self-hosted-wcf-rest-service-and-basic-authentication – Alex

+0

Nó không chính xác giúp, như vậy, nhưng nó cung cấp hỗ trợ đạo đức và giải thích :) – adhocgeek

+0

Thực ra, tôi lấy lại điều đó, tôi đã không đọc đủ xa để thấy rằng có một giải pháp trên đó, giống như một giải pháp được đăng và chấp nhận về câu hỏi này. – adhocgeek

Trả lời

7

Hãy thử điều này:

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; 
} 

Theo như tôi biết đây là một kỹ thuật không có giấy tờ mà dựa vào cách WCF chồng quản lý ngoại lệ trong nội bộ. Có phải là một cách tài liệu nhưng tôi đã không tìm thấy một.

+0

Bạn đã khám phá điều này ở đâu? :) Nó hoạt động, nhưng nó đã cho tôi suy nghĩ về việc liệu tôi thực sự muốn sử dụng WCF bây giờ ... – adhocgeek

+0

Tôi nhìn vào mã WCF bằng cách sử dụng Reflector. –

Các vấn đề liên quan