I\'m working on custom WCF authentication and authorization and found some articles about UserNamePasswordValidator and ServiceAuthorizationManager.
<You're right, the documentation on this is no help at all.
The way I have used this class is as follows. Override the Authenticate() method to:
You can't just set the thread principal at this point as it is changed later on by WCF.
The code in the ServiceAuthenticationManager.Authenticate() methods would look something like this:
public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
{
int tokenPosition = message.Headers.FindHeader("Token", "http://customnamespace.org");
string token = message.Headers.GetHeader<string>(tokenPosition);
IPrincipal user = new CustomPrincipal(token);
message.Properties["Principal"] = user;
return authPolicy;
}
Then you add a custom authorization policy that
The code in the IAuthorizationPolicy() method would look like
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
IPrincipal user = OperationContext.Current.IncomingMessageProperties["Principal"] as IPrincipal;
evaluationContext.Properties["Principal"] = user;
evaluationContext.Properties["Identities"] = new List<IIdentity> { user.Identity };
IList<Claim> roleClaims = this.GetRoleClaims(user);
evaluationContext.AddClaimSet(this, new DefaultClaimSet(this.Issuer, roleClaims));
return true;
}
In the service behaviour configuration, you need to set principalPermissionMode="Custom" in order for WCF to set the IPrincipal as the principal on the executing thread for the actual service operation invocation.
<serviceAuthorization principalPermissionMode="Custom"...