Every once in a while the question comes up how to extend WCF with custom credential types. It turns out that most of the time people don’t really want to invent custom tokens or credential types, but rather want to extend username/password style of credentials (e.g. username/password/customer ID). Unfortunately the UserName token does not support this type of extensibility but there are several options to accomplish this:
- If your extensibility requirements are very simple you could try to encode all the information into the username and password fields of a UserName credential. You’d need some extra plumbing on the service side (UserNamePasswordValidator, custom IPrincipal) to decode the information again and provide normalized user information.
- You could use SOAP headers to transmit the additional information. This has the potential to pollute your business logic with security plumbing and needs some wrapping. There are also some gotchas around adding headers on the fly, as well as protecting them.
- You could write a full fledged custom credential that supports the extensibility you need. Unfortunately this is not the best documented area of WCF and you are mostly on your own. The WCF credential infrastructure is extremely flexible – but I wouldn’t call it an extensibility point – but rather a replacement point. You end up replacing a number of classes on the service and client side to make this happen (see here for an overview). I did that for a username/password/namevalue credential and it wasn’t a pleasant experience.
- You could use a standard token type in WCF that already supports all the extensibility needs you might have – e.g. SAML. The problem here is that SAML and issued tokens are not very accessible through plain WCF – but Geneva makes it much easier to use them – even without a security token service. That’s the option I am going to look at in the next post.