使用CodeAccessSecurity的WCF声明性安全性

时间:2011-09-02 16:16:25

标签: wcf authorization code-access-security

我打算使用基于CodeAccessSecurity的基于权限的自定义声明授权机制。为了实现它,我创建了以下从CodeAccessSecurityAttribute派生的子类:

[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class RequirePermissionAttribute : CodeAccessSecurityAttribute {

    private static readonly IPermission _deny = new SecurityPermission(PermissionState.None);
    private static readonly IPermission _allow = new SecurityPermission(PermissionState.Unrestricted);

    public RequirePermissionAttribute(SecurityAction action)
        : base(action) {
    }

    public string Permission { get; set; }

    public override IPermission CreatePermission() {
        if (User.HasPermission(Permission))
            return _allow;
        else
            return _deny;
    }
}

我这样使用它:

[ServiceContract]
public class Service {

    [OperationContract]
    [RequirePermission(SecurityAction.Demand, Permission = "GetArbitaryProduct")]
    public User GetProduct(string name) {
        return _productRepository.Get(name);
    }
}

我希望如果CreatePermission方法返回_deny,则GetProduct的访问权限将受到限制。但它看起来CodeAccessSecurity不能以这种方式工作。我是否必须抛出异常才能正确限制访问?或者可能有更优雅的方式来实现这一目标?

1 个答案:

答案 0 :(得分:1)

基于CodeAccessSecurityAttribute子类实例连接权限验证的CLR机制只会在评估CreatePermission()返回的权限时抛出异常时阻止执行目标方法。由于您将SecurityAction.Demand指定为权限操作,这意味着必须抛出权限的Demand()方法以避免执行目标方法。

还有很多其他方法可以处理授权方案,其中许多方法可能会让您感觉更“优雅”。但是,在开始寻找备用方法之前,最好考虑一下授权被拒绝时服务调用者应该遵循的行为。您希望方法成功但返回null,还是您希望返回错误?如果是后者,你是否希望它是一个类型错误?