C# 使用自定义属性检查用户访问权限

C# 使用自定义属性检查用户访问权限,c#,wcf,C#,Wcf,如果会话中有用户信息,那么检查会话并允许基于提供的一个值访问用自定义属性修饰的方法的可能性有多大 所以我想做的是: public class UserAccess: System.Attribute { private string userRole; public UserAccess(string userRole) { this.userRole = userRole; } } 然后,当我像这样装饰端点时: [UserAccess

如果会话中有用户信息,那么检查会话并允许基于提供的一个值访问用自定义属性修饰的方法的可能性有多大

所以我想做的是:

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”
才能根据会话值检查实际执行它。另外,这个验证可以在自定义属性实现中完成吗?

不,您不能这样做(不能单独完成),属性只不过是编译到代码中的元数据,它们本身什么都不做。一旦你用一些属性元数据装饰了一个方法或类,你就可以使用反射,比如
GetCustomAttributes(typeof(UserAccess))
,来检索元数据并对其进行操作,这很好地说明了这一点


您可以做的是,创建一个自定义方法,该方法将使用反射来检索元数据并为您执行计算,然后在
公共响应Get(Request r)
中执行任何操作之前,您可以调用此方法,但这并不是您所要求的那种自动逻辑评估

属性仅仅是元数据,如标志、描述、附加信息。您需要自己处理这些信息。您可以在方法本身中执行此操作,也可以让一些助手类使用反射来处理它

    // 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类中。e、 例如,UserAccessAttribute

所以其他人是对的,这些属性本身什么都不做。在服务调用生命周期的某个时刻,您必须有目的地获取元数据

要做到这一点,最好的方法是自动神奇地完成,而不是总是直接在每个操作中添加检查器和服务行为。初始设置需要更多的工作,但它可以从直接操作代码中获得,并可以应用于任何操作以检查该自定义属性

基本上你有这样的属性:

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

    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


同样适用于检查员:

愿上帝保佑您做出如此全面的回应。
<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);
        }
    }
}