WCF使用CodeAccessSecurity的声明式安全
问题描述:
我打算使用基于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
不这样工作。我是否必须抛出异常来正确限制访问?或者,也许有更优雅的方式来实现呢?
答
基于CodeAccessSecurityAttribute子类实例连接权限验证的CLR机制只会在评估由CreatePermission()返回的权限时引发异常时阻止目标方法的执行。由于您将SecurityAction.Demand指定为权限操作,这意味着权限的Demand()方法必须抛出以避免执行目标方法。
还有很多其他的方式来处理授权方案,其中很多您可能会发现更多的“优雅”。但是,在开始寻找替代方法之前,最好考虑拒绝授权时服务调用方应该遵守的行为。你是否希望该方法成功,但返回null,还是希望返回错误?如果是后者,你是否希望它成为打字错误?
目前,没关系,我对呼叫者没有任何要求,所以我可以自由实现它,因为我想。但我认为这种类型的错误是首选。 – sam
如果您更喜欢键入的错误,那么使用允许您抛出SecurityException的默认路由可能是最简单的方法。这将导致WCF内部自动生成映射到WCF客户端中的SecurityAccessDeniedException的错误(http://msdn.microsoft.com/en-us/magazine/cc948343.aspx#id0070004)。 –