Built-In Token Handlers
WIF provides the following built-in token handlers:
KerberosSecurityTokenHandler validates tokens of type KerberosReceiverSecurityToken. This token type, which is used by WCF during Kerberos authentication, wraps a Windows identity and is based on a Kerberos ticket that is received in a SOAP message. This token type is not used in SPNego or SSPI authentication.
This handler does not implement any other token handler methods, such as ReadToken or WriteToken. This is because, unlike other token types such as SAML and X.509, the KerberosReceiverSecurityToken has no wire-serializable form.
MembershipUserNameSecurityTokenHandler and WindowsUserNameSecurityTokenHandler both derive from UserNameSecurityTokenHandler, and both handle tokens of type UsernameSecurityToken. These handlers are mutually exclusive and differ only in the way they handle tokens. MembershipUserNameSecurityTokenHandler allows the specification of a
MembershipProvider to validate tokens. WindowsUserNameSecurityTokenHandler validates the token by mapping the user to a windows account. These two token handlers must not be combined in the same token handler collection.
Finally, there is a token type that does not have a handler: The WindowsSecurityToken used by WCF. This token wraps a Windows identity. It is used when a Windows token is presented during transport-level authentication, such as over a net.tcp transport. It always appears in the bootstrap token collection.
You can extract the Windows identity from a WindowsSecurityToken and convert it to an IClaimsIdentity as follows:
IClaimsIdentity rehydratedIdentity = new WindowsClaimsIdentity( (token as WindowsSecurityToken).WindowsIdentity.Token, (token as WindowsSecurityToken).WindowsIdentity.AuthenticationType);
WIF also provides the following token handlers for token types that are not directly concerned with authentication:
EncryptedSecurityTokenHandler handles tokens of type EncryptedSecurityToken. This token type provides encryption for token types that do not natively support it. For example, a SAML 1.1 token does not know how to encrypt itself. So, to issue an encrypted SAML11 assertion, wrap a SAML security token with an EncryptedSecurityToken and provide appropriate EncryptingCredentials.
EncryptedSecurityTokenHandler invokes its containing collection in order to process a security token after decryption. When an EncryptedSecurityTokenHandler is added to a collection, the ContainingCollection property is automatically set to point to the parent collection. The decryption of a token is hence a two-stage process. The first stage is conversion from the raw encrypted form to an unencrypted form, and is handled by the EncryptedSecurityTokenHandler. Then the containing collection is invoked with the unencrypted token in order to further convert from the token XML to an in-memory
The EncryptedSecurityTokenHandler also processes encrypted keys stored inside tokens.
SecurityTokenService has an internal token creation pipeline, implemented in Issue that looks like this:
Call GetScope. This method retrieves the relying party information.
Call CreateSecurityTokenDescriptor. This method simply creates a SecurityTokenDescriptor based on the scope information from step 1.
Call GetSecurityTokenHandler. The parameter is the token type from the RequestSecurityToken that was passed to Issue.
Call GetIssuerName and add the issuer name (the STS’s name) to the token descriptor.
Call GetTokenLifetime and add the token lifetime to the token descriptor.
Call GetProofToken and add the proof token descriptor to the token descriptor.
Call GetOutputClaimsIdentity and add the collection of output subjects to the token descriptor.
Call CreateToken. This method is implemented by the Security Token Handler. The parameter is the security token descriptor that we’ve created.
Call GetResponse. This method gets the RequestSecurityTokenResponse.
Normally, when you develop an STS, you simply create a class that derives from SecurityTokenService and implement GetScope and GetOutputClaimsIdentity. If you want more control over token handling, you can override any of the methods listed here.