SecurityTokenManager in WSE 2.0

The idea of SecurityTokenManager is very powerful.  It provides one single place to extend the WSE built-in token infrastructure.   You can only have one token manager registered for each token type.  

Here is a list of things that you can override:

1. Deserialization of an xml element

public override SecurityToken LoadTokenFromXml(XmlElement element) 

{

    // your ideal way to deserialize a token

    Note this deserialization will not only happen for the token appearing under the security header, this process could also happen in other places where an xml element is presented and a security token object is desired.  For example, in the WS-Trust, there is a RequestedSecurityToken element which could contains a Security token.  No surprise, WSE runtime will consult a token manager for deserialization.

2. KeyInfo resolution

public override SecurityToken LoadTokenFromKeyInfo(KeyInfo keyInfo)

{

      // you can customize your keyinfo in whatever way you want

     // this is the place to tell WSE, given a keyInfo, how to finds the token

}

KeyInfo is like a key to locate a token.  The keyInfo can contain a <SecurityTokenReference Reference="#id"> to reference a in-message token. Optionally, it can also contain a KeyIdentifier to points to a token outside the message.  KeyInfo can also contain some abitrarary element, and it will be presented as keyInfoNode which just has save the child element of the <KeyInfo> in the Value property.  Now in WSE 2.0, whenever you encouter a KeyInfo, no matter where it is, in the configruation file, e.g. the server token in the web.config, or inside the Signature element, or EncryptedKey, or EncryptedData, WSE runtime can invoke this very method to resolve a token from a keyinfo. Isn't that beautiful?

3. Deserialization of a security token assertion

 public override ISecurityTokenAssertion LoadSecurityTokenAssertion(XmlElement element)

{

      // you need to override this one when you have a customized security token assertion in your policy file

     // check out the customPolicyAssertion quickstart for more details

}

This is very similar to #1 except this applies to policy file instead of the real message.

4. SecurityTokenAssertion resolution

public override LoadTokenFromSecurityTokenAssertion(ISecuirtyTokenAssertion sta)

{

         // override this one when you have a customized a secuirty token assertion

         // and you want to tell WSE runtime how to get back a security token based on that

}

This is very similar to #2, except this applies to the policy file instead of the real message.

There are also other overridable methods which you can check out from the SecurityTokenManager reference docs. One thing i want to point out is that for convenience, SecurityTokenManager.cs class also provides a list of static methods to help pick the right token manager and invoke the method upon them.  For example, if you know that an xml element is a serialized version of security token, you can call SecurityTokenManager.GetTokenFromXml(element).  WSE runtime will try to figure out the security token manager based on the token type first and invoke the LoadTokenFromXml() method if it finds one. 

Now supposed you have written a custom security token manager, how to register it?

If it is a binarySecurityToken,

<microsoft.web.services2>

     <secuirty> 

          <binarySecurityTokenManager valueType="<insert valueType uri string here>" type="<insert type reference here>">

    </secuirty>

</microsoft.web.services2>

other wise, it must be an xml security token

<microsoft.web.services2>

     <security>

       <securityTokenManager qname="<insert qualified name here>" type="<insert type reference here>" >

    </secuirty>

</microsoft.web.services2>

Please check out the CustomBinarySecurityToken and CustomXmlSecurityToken Quickstart sample for more concrete examples.