2013-07-24 34 views
5

Có thông tin người dùng trong Phiên, làm cách nào để kiểm tra phiên và cho phép truy cập vào phương pháp được trang trí với thuộc tính tùy chỉnh dựa trên một trong các giá trị được cung cấp.Kiểm tra quyền truy cập của người dùng bằng các thuộc tính tùy chỉnh

Vì vậy, những gì tôi đang cố gắng làm là:

public class UserAccess: System.Attribute 
{ 
    private string userRole; 

    public UserAccess(string userRole) 
    { 
     this.userRole = userRole; 

    } 
} 

Sau đó, khi tôi trang trí một thiết bị đầu cuối như thế này:

[UserAccess(userRole = "Residents")] 
public Response Get(Request r){ 
    ///-- Implementation 
} 

Bằng cách nào đó khi thiết bị đầu cuối được gọi chỉ userRole = "Residents" thực sự có thể thực hiện nó dựa kiểm tra giá trị phiên. Ngoài ra, xác thực này có thể được thực hiện trong triển khai thuộc tính tùy chỉnh không?

Trả lời

17

Vì vậy, những người khác đúng, rằng các thuộc tính không làm gì cả. Nó chỉ là siêu dữ liệu mà bạn phải cố tình nhận được tại một số điểm trong suốt cuộc đời của cuộc gọi dịch vụ.

Cách tốt nhất để thực hiện điều đó vì vậy nó được thực hiện tự động một cách kỳ diệu và không phải lúc nào cũng trực tiếp trong mọi hoạt động là thêm người kiểm tra và hành vi dịch vụ. Đó là nhiều công việc để thiết lập ban đầu, nhưng nó được rằng ra khỏi mã hoạt động trực tiếp của bạn và có thể làm cho nó áp dụng cho bất kỳ hoạt động để kiểm tra cho rằng thuộc tính tùy chỉnh.

Về cơ bản bạn có thuộc tính của bạn như vậy:

namespace MyCustomExtensionService 
{ 
    public class UserAccessAttribute : System.Attribute 
    { 
     private string _userRole; 

     public UserAccessAttribute(string userRole) 
     { 
      _userRole = userRole; 

      //you could also put your role validation code in here 

     } 

     public string GetUserRole() 
     { 
      return _userRole; 
     } 
    } 
} 

Sau đó, bạn thiết lập thanh tra của bạn thông số (lưu ý có thanh tra viên khác mà bạn có thể sử dụng):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using System.ServiceModel; 
using System.ServiceModel.Description; 
using System.ServiceModel.Dispatcher; 
using System.Web; 

namespace MyCustomExtensionService 
{ 
    public class MyParameterInspector : IParameterInspector 
    { 

     public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) 
     { 
      //throw new NotImplementedException(); 
     } 

     public object BeforeCall(string operationName, object[] inputs) 
     { 
      MethodInfo method = typeof(Service1).GetMethod(operationName); 
      Attribute[] attributes = Attribute.GetCustomAttributes(method, typeof(UserAccessAttribute), true); 

      var attr = (UserAccessAttribute)attributes.First(); 

      if (attributes.Any()) 
      { 
       var userHasProperAuthorization = true; 
       if (attr.GetUserRole() == "Residents" && userHasProperAuthorization) 
       { 
        //everything is good, continue to operation 
       } 
       else 
       { 
        throw new FaultException("You do not have the right security role!"); 
       } 
      } 



      return null; 

     } 
    } 
} 

Sau đó, bạn thiết lập hành vi đầu cuối của bạn (có các hành vi khác mà bạn có thể sử dụng):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.ServiceModel.Description; 
using System.ServiceModel.Dispatcher; 
using System.Web; 

namespace MyCustomExtensionService 
{ 
    public class MyCustomAttributeBehavior : IEndpointBehavior 
    { 
     public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
     { 
      //throw new NotImplementedException(); 
     } 

     public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) 
     { 
      foreach (ClientOperation clientOperation in clientRuntime.Operations) 
      { 
       clientOperation.ParameterInspectors.Add(
        new MyParameterInspector()); 
      } 
     } 

     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) 
     { 
      foreach (DispatchOperation dispatchOperation in endpointDispatcher.DispatchRuntime.Operations) 
      { 

       dispatchOperation.ParameterInspectors.Add(
        new MyParameterInspector()); 
      } 
     } 

     public void Validate(ServiceEndpoint endpoint) 
     { 
      //throw new NotImplementedException(); 
     } 
    } 
} 

Sau đó, bạn tạo y phần hành vi của chúng tôi:

using System.Linq; 
using System.ServiceModel.Configuration; 
using System.Web; 

namespace MyCustomExtensionService 
{ 
    public class MyBehaviorSection : BehaviorExtensionElement 
    { 

     protected override object CreateBehavior() 
     { 
      return new MyCustomAttributeBehavior(); 

     } 

     public override Type BehaviorType 
     { 

      get { return typeof(MyCustomAttributeBehavior); } 


     } 
    } 
} 

Sau đó, bạn thiết lập cấu hình để sử dụng các hành vi mới:

<system.serviceModel> 
    <services> 
     <service name ="MyCustomExtensionService.Service1"> 
     <endpoint address="" behaviorConfiguration="MyCustomAttributeBehavior" 
      binding="basicHttpBinding" contract="MyCustomExtensionService.IService1"> 
     </endpoint> 
     </service> 
    </services> 
    <extensions> 
     <behaviorExtensions> 
     <add name="Validator" type="MyCustomExtensionService.MyBehaviorSection, MyCustomExtensionService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
     </behaviorExtensions> 
    </extensions> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="MyCustomAttributeBehavior"> 
      <Validator /> 
     </behavior> 
     </endpointBehaviors> 

đây là giao diện dịch vụ - với một hoạt động mà sẽ làm việc và một trong đó sẽ thất bại do có sai người dùng truy cập

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Text; 

namespace MyCustomExtensionService 
{ 

    [ServiceContract] 
    public interface IService1 
    { 

     [OperationContract] 
     string GetData(int value); 

     [OperationContract] 
     string GetDataUsingWrongUserAccess(int value); 

    } 



} 

Và các dịch vụ hoạt động:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Text; 

namespace MyCustomExtensionService 
{ 

    public class Service1 : IService1 
    { 
     [UserAccess("Residents")] 
     public string GetData(int value) 
     { 
      return string.Format("You entered: {0}", value); 
     } 

     [UserAccess("Admin")] 
     public string GetDataUsingWrongUserAccess(int value) 
     { 
      return string.Format("You entered: {0}", value); 
     } 
    } 
} 

Mọi chi tiết, xem MSDN http://msdn.microsoft.com/en-us/library/ms730137.aspx

còn cho thanh tra viên: http://cgeers.com/2008/11/09/wcf-extensibility-parameter-inspectors/

+0

Wow .. Đó là rất nhiều mã .. Cảm ơn – user1791567

+1

Thiên Chúa chúc lành cho bạn cho một phản ứng toàn diện như vậy. – Jeremy

0

Không, bạn không thể làm điều đó (không phải bởi chính nó), thuộc tính không có gì hơn siêu dữ liệu được biên dịch vào mã của bạn, bởi chính họ không làm gì cả. Khi bạn trang trí một phương pháp hoặc lớp học với một số siêu dữ liệu thuộc tính, bạn có thể sử dụng phản chiếu, như GetCustomAttributes(typeof(UserAccess)), để truy xuất siêu dữ liệu và hành động theo nó, điều này SO answer minh họa điều này khá tốt

Điều bạn có thể làm là tạo phương thức tùy chỉnh sẽ sử dụng sự phản chiếu để lấy siêu dữ liệu và thực hiện đánh giá cho bạn, sau đó bên trong public Response Get(Request r), trước khi bạn làm bất cứ điều gì bạn có thể gọi phương pháp này, nhưng đây không phải là loại đánh giá tự động hóa mà bạn đang yêu cầu

+0

Đồng ý .. Tôi nghĩ mình tốt hơn được đối tượng ra khỏi phiên và đánh giá nó ... – user1791567

1

chỉ siêu dữ liệu như cờ, mô tả, thông tin bổ sung. Bạn cần tự mình xử lý thông tin này. Bạn có thể làm điều này trong chính phương thức đó hoặc có một số lớp trợ giúp để xử lý nó bằng cách sử dụng sự phản chiếu.

// Using reflection. 
    MethodInfo method = typeof(ClassName).GetMethod("Get"); 
    Attribute[] attributes = Attribute.GetCustomAttributes(method, typeof(UserAccess), true); 


    // Displaying output. 
    foreach (var attr in attributes) 
    { 
     if (attr is UserAccess) 
     { 
      var ua = (UserAccess)attr; 
      System.Console.WriteLine("{0}",a.userRole); 
     } 
    } 

* Tôi cũng đề nghị với hậu tố từ Thuộc tính đến lớp UserAccess của bạn như là một quy ước. ví dụ: UserAccessAttribute

+0

Đây là giá trị để xem xét .. thanks – user1791567

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