In my previous post I mentioned that Geneva takes over parts of the WCF security system – I used the example of certificate validation. This is also true for username/password authentication.
In the case you have an existing service with a UserNamePasswordValidator – as soon as you opt-into Geneva, the validator will stop to work. This is because Geneva takes over parts of the WCF processing pipeline and injects its own token parsing and validation system.
In Geneva, so-called SecurityTokenHandlers read and validate incoming tokens. As part of the validation process, claims based on that token are created and put into the IClaimsPrincipal, which will abe vailable from your operations. There are two handlers that register for UserName tokens: WindowsUserNameSecurityTokenHandler and MembershipUserNameSecurityTokenHandler (I guess it is clear which account stores they use).
By default the Windows handler is registered and unless you have a used a username/password pair that incidentally matches a Windows account on your system, username authentication will fail.
You now have two options: using the membership handler (if you have an existing membership provider) or write your own handler, which is pretty straightforward. The following handler code makes sure that username and password are identical – nothing you should do in your production systems – but you get the idea ;)
class SimpleUserNameSecurityTokenHandler : UserNameSecurityTokenHandler
{
public override ClaimsIdentityCollection ValidateToken(SecurityToken token)
{
UserNameSecurityToken unToken = token as UserNameSecurityToken;
if (unToken == null)
{
throw new ArgumentException(“token”);
}
// replace with proper password validation!
if (unToken.UserName != unToken.Password)
{
throw new SecurityTokenValidationException();
}
ClaimsIdentity id = new ClaimsIdentity(new List<Claim>
{
new Claim(WSIdentityConstants.ClaimTypes.Name, unToken.UserName)
}, “UserName”);
return new ClaimsIdentityCollection(id);
}
public override bool CanValidateToken
{
get
{
return true;
}
}
}
You have to setup the handler in config – this is currently a little cumbersome but will hopefully get easier in the future. You first have to remove the windows handler – or clear the handler collection and add your own handler to it:
<microsoft.identityModel>
<securityTokenHandlers>
<clear />
<add type=“LeastPrivilege.SimpleUserNameSecurityTokenHandler, AutoClaims“ />
</securityTokenHandlers>
</microsoft.identityModel>
There is also a thread on MSDN where Pedro shows how to do that programmatically.
HTH