How to decrypt a GenericXmlSecurityToken using Geneva Framework

 

This took some time and you are lucky if you hit this after a search. This extension method allows you to decrypt a SAML 1.1 security token using Geneva Framework.

public static ClaimsIdentityCollection ToClaimsIdentityCollection(this GenericXmlSecurityToken token, string thumbprintPrivateKey, string thumbprintIssuerPublicKey, TrustVersion trustVersion)
{
    // Decrypt token
    var tokenString = new StringReader(token.TokenXml.OuterXml);
    var reader = XmlReader.Create(tokenString);

    // Resolver
    X509Certificate2 privateKey = CertificateUtility.GetCertificateByThumbprint(StoreName.My, StoreLocation.LocalMachine, thumbprintPrivateKey);
    X509SecurityToken privateKeyToken = new X509SecurityToken(privateKey);
    X509Certificate2 issuerKey = CertificateUtility.GetCertificateByThumbprint(StoreName.TrustedPeople, StoreLocation.LocalMachine, thumbprintIssuerPublicKey);
    X509SecurityToken issuerKeyToken = new X509SecurityToken(issuerKey);
    List<SecurityToken> tokens = new List<SecurityToken>();
    tokens.Add(privateKeyToken);
    tokens.Add(issuerKeyToken);
    SecurityTokenResolver outOfBandTokenResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(tokens), false);

    var samlHandler = SecurityTokenHandlerCollection.DefaultHandlers.SingleOrDefault(handler => handler is Saml11SecurityTokenHandler) as Saml11SecurityTokenHandler;
    samlHandler.SamlSecurityTokenRequirement.IssuerTokenResolver = outOfBandTokenResolver;
    EncryptedSecurityTokenHandler h = new EncryptedSecurityTokenHandler(outOfBandTokenResolver, new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { samlHandler }));
    var serializer2 = new SecurityTokenSerializerAdapter(
        new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { h }),
        SecurityVersion.WSSecurity11,
        trustVersion,
        trustVersion == TrustVersion.WSTrust13 ? SecureConversationVersion.WSSecureConversation13 : SecureConversationVersion.WSSecureConversationFeb2005,
        false,
        null,
        null,
        null);
    var samlSecurityToken = serializer2.ReadToken(reader, outOfBandTokenResolver);

    samlHandler.SamlSecurityTokenRequirement.IssuerNameRegistry = new NullIssuerNameRegistry();

    var handlers = new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { samlHandler });
    var claims = handlers.ValidateToken(samlSecurityToken);

    return claims;
}

The way to use it:

var token = GetTokenFromSomewhere();
token.ToClaimsIdentityCollection( "thmbprint of the cert used to decrypt the token", 
                                  "thmbprint of the cert used to check the signature of the issuer", 
                                  TrustVersion.WSTrust13 or TrustVersion.WSTrustFeb2005 );

Download it from here

Published: November 19 2008

blog comments powered by Disqus