2013-07-24 2 views
5

세션에 사용자 정보가 있으면 가능한 한 세션을 확인하고 제공된 값 중 하나를 기반으로 사용자 지정 특성으로 장식 된 메서드에 액세스 할 수 있습니다.사용자 지정 특성을 사용하여 사용자 액세스 확인

그래서 난 할 노력하고있어입니다 :

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

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

    } 
} 

그럼이 같은 엔드 포인트 장식 할 때 : 엔드 포인트가 호출

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

어떻게 든 경우에만 userRole = "Residents" 실제로 기반으로 실행할 수 있습니다 세션 값을 확인하십시오. 또한이 유효성 검사를 사용자 지정 특성 구현에서 수행 할 수 있습니까?

답변

17

그래서 다른 사람들은 옳습니다. 속성 자체는 아무 것도하지 않습니다. 서비스 호출 기간 동안 의도적으로 얻은 메타 데이터 일뿐입니다.

이렇게하는 가장 좋은 방법은 마술처럼 자동으로 수행되고 모든 작업에서 항상 직접 수행되는 것은 아니지만 검사자와 서비스 동작을 추가하는 것입니다. 처음에는 설정하는 것이 더 많은 작업이지만 직접 작업 코드에서 해당 작업을 가져와 모든 작업에 적용하여 해당 사용자 지정 특성을 확인하도록 할 수 있습니다.기본적으로

당신은 다음처럼 속성이 있습니다

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; 

     } 
    } 
} 

그런 다음 설치 엔드 포인트의 행동 :

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

그런 다음 당신은 당신의 매개 변수 관리자 (다른 검사는 사용할 수 있습니다주의)을 설정 (당신이 사용할 수있는 다른 행동들이 있습니다) :

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

그런 다음 y 우리의 행동 섹션 :

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


     } 
    } 
} 

그런 다음 설치 새 동작 사용할 수있는 설정 : - 하나 개의 작업으로 작업 인해를 데 실패 한 것입니다 여기

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

는 서비스 인터페이스 잘못된 사용자 액세스

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

    } 



} 

그리고 서비스 운영 :

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

더 많은 정보 검사기도

MSDN http://msdn.microsoft.com/en-us/library/ms730137.aspx를 참조하십시오 http://cgeers.com/2008/11/09/wcf-extensibility-parameter-inspectors/

+0

와우 .. 코드가 많습니다. 감사합니다. – user1791567

+1

감사합니다. – Jeremy

0

아니요, 그 자체로는 할 수 없습니다. 속성은 코드에 컴파일 된 메타 데이터 이상으로 아무 것도하지 않습니다. 당신은 몇 가지 속성 메타 데이터와 메소드 나 클래스를 장식하면 다음이 SO answer 꽤 잘

당신이 할 수있는 무엇이, 사용자 정의 메소드를 생성 설명, 그것을 바탕으로 메타 데이터와 행위를 검색, GetCustomAttributes(typeof(UserAccess))처럼 반사를 사용할 수 있습니다 리플렉션을 사용하여 메타 데이터를 검색하고 평가를 수행 한 다음 public Response Get(Request r) 내부에서이 메소드를 호출 할 수 있습니다. 그러나 이것은 정확히 사용자가 요구하는 자동 검색 평가 유형이 아닙니다.

+0

동의 .. 내가 더 나은 세션에서 객체를 얻고 그것을 평가하는 생각 ... – user1791567

1

속성은 다음과 같습니다. 국기, 설명, 와 같은 단순한 메타 데이터. 이 정보는 직접 처리해야합니다. 메서드 자체에서이 작업을 수행하거나 리플렉션을 사용하여 처리 할 수있는 도우미 클래스를 가질 수 있습니다.

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

*이 또한 대회와 같은 UserAccess 클래스에 단어 특성 접미사하는 것이 좋습니다. 예 : UserAccessAttribute

+0

을이 고려해야 할 가치가있다 .. 감사합니다 – user1791567

관련 문제