2010-09-02 41 views
6

Tôi cần chuyển giá trị từ máy khách mỗi lần yêu cầu gửi đến WCF và kiểm tra giá trị đó trên máy chủ và quyết định đưa ra yêu cầu hay không, bất kỳ ai có thể viết ví dụ về điều đó không? sẽ được triển khaiWCF và xác thực

trường hợp: im tạo khóa dựa trên phần cứng của máy khách và tôi muốn gửi khóa đó tới máy chủ với mọi yêu cầu kiểm tra xem khóa có được chấp nhận trong máy chủ hay không và sau đó quyết định xử lý yêu cầu hay không.

cảm ơn trước.

+1

Xem http://stackoverflow.com/questions/964433/how-to-add-a-custom-header-to-every-wcf-calls để tự động chuyển dữ liệu dưới dạng tiêu đề. Tôi không biết làm thế nào để tự động kiểm tra nó trên máy chủ, tuy nhiên, nhưng tôi mong đợi có một cái móc. – Rup

Trả lời

1

đầu tiên chúng ta cần phải thực hiện hành vi và thanh tra viên ở phía khách hàng để gửi chính để xác thực client:

class AuthenticationBehaviour : IEndpointBehavior 
{ 
    #region IEndpointBehavior Members 

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) 
    { 
     AuthenticationMessageInspector inspector = new AuthenticationMessageInspector(); 
     clientRuntime.MessageInspectors.Add(inspector); 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) 
    { 
     //AuthenticationMessageInspector inspector = new AuthenticationMessageInspector(); 
     //endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector); 
    } 

    public void Validate(ServiceEndpoint endpoint) 
    { 
    } 

    class AuthenticationMessageInspector : IClientMessageInspector 
{ 
    private const string HeaderKey = "Authentication"; 

    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 

     if (Session.MachineId == 0) 
     { 
      Session.MachineId = LicenseGenerator.GenerateLicense(); 
     } 


     request.Headers.Add(MessageHeader.CreateHeader(HeaderKey, string.Empty, Session.MachineId)); 
     return null; 
    } 

    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 

    } 
} 

bây giờ chúng ta cần phải thực hiện hành vi và thanh tra trong máy chủ bên (dịch vụ WCF) để kiểm tra mọi yêu cầu thực hiện và trích xuất các tiêu đề sau đó xác nhận điều đó:

public class AuthenticationBehaviour : IEndpointBehavior 
{ 
    #region IEndpointBehavior Members 

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) 
    { 
     //AuthenticationMessageInspector inspector = new AuthenticationMessageInspector(); 
     //clientRuntime.MessageInspectors.Add(inspector); 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) 
    { 
     AuthenticationMessageInspector inspector = new AuthenticationMessageInspector(); 
     endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector); 
     //Console.WriteLine("Dispatcher Applied!"); 
    } 

    public void Validate(ServiceEndpoint endpoint) 
    { 
    } 

    #endregion 
} 

    public class AuthenticationMessageInspector : IDispatchMessageInspector 

{ 

    #region Members 
    private string conStr = "", commStr = ""; 
    public IDbConnection Connection { get; set; } 
    public IDbCommand Command { get; set; } 
    public IDataReader Reader { get; set; } 

    #endregion   
    private const string HeaderKey = "Authentication"; 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     //Console.WriteLine("recieved Request! "); 
     int headerIndex = request.Headers.FindHeader(HeaderKey, string.Empty); 
     if (headerIndex < 0 || string.IsNullOrEmpty(request.Headers.GetHeader<String>(headerIndex))) 
     { 

      throw (new Exception("Access Denied!\n")); 
      return null; 
     } 


     bool valid = Validate(request.Headers.GetHeader<String>(headerIndex)); 
     if (!valid) 
     { 
      Console.WriteLine("recieved Request! From " + request.Headers.GetHeader<String>(headerIndex) + " and Access Denied!\n"); 
      throw (new Exception("Access Denied!\n" + request.Headers.GetHeader<String>(headerIndex) + " License Number is not athourized! "));   
     } 
     if (headerIndex != -1) 
     { 
      Console.WriteLine("recieved Request! From " + request.Headers.GetHeader<String>(headerIndex)); 
     } 
     return null; 

    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 

    } 
} 

bây giờ cho phép đăng ký hành vi:

  _routingHost.Description.Endpoints[0].Behaviors.Add(new Gateway.Controllers.AuthenticationBehaviour()); 
_routingHost.Open(); 

đó là cảm ơn.

2

Bạn đang tìm kiếm thanh tra thư. Kiểm tra số article này.

Chỉnh sửa:

Cách tiếp cận được đề cập là cách dễ nhất trong trường hợp của bạn. Bạn sẽ tạo trình kiểm tra thư khách hàng để thêm trình kiểm tra thông điệp tiêu đề và công cụ tùy chỉnh để trích xuất tiêu đề và xác thực khóa. Nếu khóa không hợp lệ, bạn sẽ ném một ngoại lệ.

Giải pháp sạch là tạo ra custom tokencutom credentials nhưng nó thực sự phức tạp, trừ khi bạn muốn đi sâu vào việc thực hiện bảo mật WCF sử dụng thanh tra thư.

+0

im tạo khóa dựa trên phần cứng của máy khách và tôi muốn gửi khóa đó tới máy chủ với mọi yêu cầu để kiểm tra xem khóa có được chấp nhận trong db máy chủ hay không và sau đó quyết định xử lý yêu cầu hoặc không – Stacker

+0

Vậy đó có phải là xác thực (chỉ cần kiểm tra xem máy khách có khóa có thể truy cập dịch vụ) hay ủy quyền (các khóa khác nhau có thể sử dụng các bộ hoạt động khác nhau) không? –

+0

chỉ cần kiểm tra xem máy khách có khóa có thể truy cập dịch vụ – Stacker

1

Tôi đã triển khai một cái gì đó như thế này để đối phó với một số xác thực "tùy chỉnh" đặc biệt trong đó các phương thức được phép hoặc bị từ chối dựa trên trạng thái cơ sở dữ liệu. Nó sử dụng PerSession thực hiện, cho phép bạn tránh đi qua khóa đó mọi lúc, vì bạn có thể duy trì proxy trong suốt thời gian thực thi. Nó cũng cung cấp một số lợi ích hiệu suất bằng cách loại bỏ chi phí của việc khởi tạo proxy nhiều lần (có thể không phải là một vấn đề tùy thuộc vào thiết kế của bạn).

  1. Thực hiện dịch vụ của bạn với một InstanceContextMode của "PerSession" [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
  2. Cung cấp một phương thức khởi tạo trong dịch vụ của bạn mà chấp nhận chìa khóa, và giữ một tham chiếu đến nó.
  3. Trong các phương pháp của dịch vụ của bạn, hãy kiểm tra khóa đó, các điều kiện khác, v.v. để xác định bạn cần làm gì.
  4. Bây giờ khi bạn khởi tạo proxy máy khách, hãy gọi phương thức khởi tạo đó trước tiên sẽ chuyển khóa và từ thời điểm đó trở đi bạn có thể tiếp tục thực hiện cuộc gọi mà không có nó.
+0

thực sự tôi đã thực hiện nó rồi, cảm ơn rất nhiều vì đã cố gắng giúp đỡ, tôi đã sử dụng một phương pháp khác để viết câu trả lời sớm – Stacker

0

Tôi đã đến bài viết này khi cố gắng triển khai cơ chế xác thực trên dịch vụ WCF Rest, tôi đã cố gắng lấy Header xác thực trên phương thức thanh tra thông báo tùy chỉnh AfterReceiveRequest nhưng có vấn đề truy xuất tiêu đề với System.ServiceModel đã cung cấp. Kênh.Tin đối tượng (yêu cầu var trên phương pháp chữ ký)

public object AfterReceiveRequest(ref Message request, IClientChannel channel, 
    InstanceContext instanceContext) 
    Dim headerIndex = request.Headers.FindHeader(HeaderKey, String.Empty) 

Các headerIndex sẽ luôn -1, do này, tôi nghiên cứu và phát hiện ra rằng có một phương pháp mở rộng của lớp thông điệp cho phép chuyển đổi các tin nhắn đến một đối tượng loại System.Net.Http.HttpRequestMessage. Để làm như vậy tất cả nó là cần thiết là để nhập khẩu các hội đồng sau đây: System.ServiceModel.Channel, System.Net.Http.

Dim httpReq As System.Net.Http.HttpRequestMessage = request.ToHttpRequestMessage() 

Dim authValue As String 
If httpReq.Headers.Contains(HeaderKey) Then 
    authValue = httpReq.Headers.GetValues(HeaderKey)(0) 
End If 
Các vấn đề liên quan