there comes a point where using an eavesdropping application to catch packets as they
fly between Secure Token Services and Relying Parties becomes tiresome. For
me it came when I decided to give up on creating a man-in-the-middle between SSL sessions
between ADFS and applications. Mainly because ADFS doesn’t like that.
At all.
Needless to say I wanted to see the tokens. Luckily, Windows Identity Foundation
has the solution by way of the Bootstrap token. To understand what it is, consider
how this whole process works. Once you’ve authenticated, the STS will POST a
chunk of XML (the SAML Token) back to the RP. WIF will interpret it as necessary
and do it’s magic generating a new principal with the payload. However, in some
instances you need to keep this token intact. This would be the case if you
were creating a web service and needed to forward the token. What WIF does is
generate a bootstrap token from the SAML token, in the event you needed to forward
it off to somewhere.
Before taking a look at it, let's add in some useful using statements:
using System;
using System.IdentityModel.Tokens;
using System.Text;
using System.Threading;
using System.Xml;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Tokens.Saml11;
The bootstrap token is attached to IClaimsPrincipal identity:
SecurityToken bootstrapToken = ((IClaimsPrincipal)Thread.CurrentPrincipal).Identities[0].BootstrapToken;
However if you do this out of the box, BootstrapToken will be null. By default,
WIF will not save the token. We need to explicitly enable this in the web.config
file. Add this line under <microsoft.IdentityModel><service><securityTokenHandlers>:
<securityTokenHandlerConfiguration saveBootstrapTokens="true" />
Once you’ve done that, WIF will load the token.
The properties are fairly straightforward, but you can’t just get a blob from it:
Luckily we have some code to convert from the bootstrap token to a chunk of XML:
SecurityToken bootstrapToken = ((IClaimsPrincipal)Thread.CurrentPrincipal).Identities[0].BootstrapToken;
StringBuilder sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb))
{
new Saml11SecurityTokenHandler(new SamlSecurityTokenRequirement()).WriteToken(writer, bootstrapToken);
}
string theXml = sb.ToString();
We get a proper XML document:
That’s all there is to it.