使用 CodeAccessSecurity 的 WCF 声明式安全性
我计划使用基于 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
不能以这种方式工作。我是否必须抛出异常才能正确限制访问?或者也许有更优雅的方法来实现这一目标?
I'm planning to use custom permission-based declarative authorization mechanism based on CodeAccessSecurity
. In order to implement it I've created following subclass derived from 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;
}
}
I use it this way:
[ServiceContract]
public class Service {
[OperationContract]
[RequirePermission(SecurityAction.Demand, Permission = "GetArbitaryProduct")]
public User GetProduct(string name) {
return _productRepository.Get(name);
}
}
And I expected that if CreatePermission
method returns _deny
access to GetProduct
will be restricted. But it looks that CodeAccessSecurity
doesn't work this way. Do I have to throw an exception to restrict access properly? Or maybe there is more elegant way to achieve that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基于 CodeAccessSecurityAttribute 子类实例连接权限验证的 CLR 机制仅在评估 CreatePermission() 返回的权限时抛出异常时才会阻止目标方法的执行。由于您将 SecurityAction.Demand 指定为权限操作,这意味着权限的 Demand() 方法必须抛出异常以避免执行目标方法。
还有很多其他方法可以处理授权场景,您可能会发现其中许多更“优雅”。但是,在开始寻找替代方法之前,最好考虑一下当授权被拒绝时,服务调用者应该观察到什么行为。您希望该方法成功但返回 null,还是希望返回错误?如果是后者,您是否希望它成为类型错误?
The CLR mechanism that wires up permission verifications based on a CodeAccessSecurityAttribute subclass instance will only prevent execution of the target method if an exception is thrown when the permission returned by CreatePermission() is evaluated. Since you're specifying SecurityAction.Demand as the permission action, this means that the permission's Demand() method must throw in order to avoid execution of the target method.
There are plenty of other ways to handle authorization scenarios, many of which you might find more "elegant". However, before you start looking for alternate approaches, it would be best to consider what behaviour your service caller should observe when authorization is denied. Do you want the method to succeed but return null, or would you prefer to return a fault? If the latter, do you want it to be a typed fault or not?