Custom Principals in WCF with Geneva
WCF has an extensibility point to set your own IPrincipal implementation on Thread.CurrentPrincipal (I wrote about that here). Geneva uses this mechanism to set its IClaimsPrincipal (wrote about that here). Since the standard “slot” for custom principals is already used by Geneva, it was unclear to me how to set your own IPrincipal after Geneva has done its work. With a little help from the Geneva team (thanks Jan) – I found a way that works. You can replace the principal in a service authorization manager via the Properties collection on the authorization context. Voodoo. class AuthorizationManager : IdentityModelServiceAuthorizationManager { public override bool CheckAccess(OperationContext operationContext, ref Message message) { base.CheckAccess(operationContext, ref message);
// action header to get to the request operation string action = operationContext.IncomingMessageHeaders.Action;
// properties collection holds the principal that goes on Thread.CurrentPrincipal var properties = operationContext .ServiceSecurityContext .AuthorizationContext .Properties;
// retrieve current principal IClaimsPrincipal principal = properties["Principal"] as IClaimsPrincipal; // create custom principal var customPrincipal = new CustomClaimsPrincipal(principal, "some value"); // set the custom principal properties["Principal"] = customPrincipal; return Authorize(action, customPrincipal); }
private bool Authorize(string action, CustomClaimsPrincipal principal) { // do whatever authZ logic you have return true; } }
public class CustomClaimsPrincipal : ClaimsPrincipal { public CustomClaimsPrincipal(IClaimsPrincipal principal, string customValue) : base(principal) { CustomPropery = customValue; }
public string CustomPropery { get; set; } } Afterwards register this class in the ServiceAuthorizationBehavior. Be aware that this gets called on every request – so don’t put expensive operations in the custom principal creation code. IdentityModel | WCF
Thursday, April 02, 2009 9:01:34 AM UTC
|