我打算使用基于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
不能以这种方式工作。我是否必须抛出异常才能正确限制访问?或者可能有更优雅的方式来实现这一目标?
答案 0 :(得分:1)
基于CodeAccessSecurityAttribute子类实例连接权限验证的CLR机制只会在评估CreatePermission()返回的权限时抛出异常时阻止执行目标方法。由于您将SecurityAction.Demand指定为权限操作,这意味着必须抛出权限的Demand()方法以避免执行目标方法。
还有很多其他方法可以处理授权方案,其中许多方法可能会让您感觉更“优雅”。但是,在开始寻找备用方法之前,最好考虑一下授权被拒绝时服务调用者应该遵循的行为。您希望方法成功但返回null,还是您希望返回错误?如果是后者,你是否希望它是一个类型错误?