2011-09-02 67 views
1

我打算使用基于CodeAccessSecurity的基于自定义许可的声明式授权机制。为了实现它,我已经创建了从0​​得出以下子类:WCF使用CodeAccessSecurity的声明式安全

[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

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

还有很多其他的方式来处理授权方案,其中很多您可能会发现更多的“优雅”。但是,在开始寻找替代方法之前,最好考虑拒绝授权时服务调用方应该遵守的行为。你是否希望该方法成功,但返回null,还是希望返回错误?如果是后者,你是否希望它成为打字错误?

+0

目前,没关系,我对呼叫者没有任何要求,所以我可以自由实现它,因为我想。但我认为这种类型的错误是首选。 – sam

+0

如果您更喜欢键入的错误,那么使用允许您抛出SecurityException的默认路由可能是最简单的方法。这将导致WCF内部自动生成映射到WCF客户端中的SecurityAccessDeniedException的错误(http://msdn.microsoft.com/en-us/magazine/cc948343.aspx#id0070004)。 –