WCF declarative security using 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 : CodeAccessSecurit开发者_如何学运维yAttribute {
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?
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?
精彩评论