1月4日
Combining WCF and AzMan authorization using EntLib
The code below is a class that authorizes a WCF web service call using EntLib's AzMan authorization provider:
public sealed class AzManAuthorizationManager : ServiceAuthorizationManager
{
private const string OperationContextPrefix = "O:";
protected override bool CheckAccessCore(OperationContext operationContext)
{
try
{
// Obtain the requested action from the context.
string action = operationContext.RequestContext.RequestMessage.Headers.Action;
// Remove the namespace part from the action.
action.Substring(action.LastIndexOf('/') + 1);
// Get the windows claim set that contains the windows identity
// and use that to authorize.
foreach (ClaimSet claimSet in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
{
WindowsClaimSet windowsClaimSet = claimSet as WindowsClaimSet;
if (windowsClaimSet != null)
{
WindowsPrincipal principal = new WindowsPrincipal(windowsClaimSet.WindowsIdentity);
IAuthorizationProvider provider = AuthorizationFactory.GetAuthorizationProvider();
return provider.Authorize(principal, OperationContextPrefix + action);
}
}
}
catch (Exception exception)
{
if (ExceptionPolicy.HandleException(exception, "Exception in Security"))
{
throw;
}
}
return false;
}
}
Notes:
- This won't work with basicHttpBinding, you'll at least have to use wsHttpBinding.
- I simply remove the namespace portion of the SOAP action. This is because AzMan doesn't allow characters like : and / in an operation name.
- When calling Authorize prefix operations with "O:". Without prefix it will instead try to find a task of the supplied name.
- EntLib's WCF Exception Shielding won't work here, any exception is converted to a SecurityAccessDeniedException so you probably want a specific exception policy that also logs the actual exception (which is what I did).
I hope you find this useful, if not let me know!