自定义CodeAccessSecurityAttribute

时间:2010-08-27 14:21:56

标签: c# .net security attributes code-access-security

我创建了以下属性:

[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class OperationPermissionAttribute : CodeAccessSecurityAttribute
{
    private static PrincipalPermission _revoke = new PrincipalPermission(PermissionState.None);
    private static PrincipalPermission _allow = new PrincipalPermission(PermissionState.Unrestricted);
    private string _role;
    private string _task;
    private string _operation;

    public OperationPermissionAttribute(SecurityAction action, string role, string task, string operation) : base(action)
    {
        _role = role;
        _task = task;
        _operation = operation;
    }

    public OperationPermissionAttribute(string role, string task, string operation)
        : base(SecurityAction.Demand)
    {
        _role = role;
        _task = task;
        _operation = operation;
    }

    public override System.Security.IPermission CreatePermission()
    {
        var principal = System.Threading.Thread.CurrentPrincipal as AzManPrincipal;
        if (principal == null)
            return _revoke;

        bool result = principal.IsOperationAllowed(_role, _task, _operation);
        return result ? _allow : _revoke;
    }
}

我这样使用:

    [OperationPermission(SecurityAction.Demand, Roles.Administrator, "UserService", "Remove")]
    public void Add(User user)
    {
        user.ValidateOrThrow();
        _repository.Add(user);
    }

运行代码会出现以下错误:

缺少必需的构造函数。 (来自HRESULT的异常:0x8013143B),它是一个COMException。

为什么我能得到它,它到底意味着什么?

2 个答案:

答案 0 :(得分:8)

问题在于构造函数定义。您需要通过仅带有SecurityAction参数的单个构造函数替换两个现有构造函数。 (请参阅http://msdn.microsoft.com/en-us/library/system.security.permissions.codeaccesssecurityattribute.aspx中的“对继承者的说明”部分。)原因在于用于权限属性的反序列化机制。

答案 1 :(得分:0)

我要将role的构造函数参数类型从String更改为Roles(在这种情况下,您还需要更改其他一些内容)

public OperationPermissionAttribute(SecurityAction action, Roles role, ...

或在构造函数调用上执行ToString()

[OperationPermission(SecurityAction.Demand, Roles.Administrator.ToString(), "UserService", "Remove")]

我个人更喜欢第一种选择。