Getting a SecurityToken from a RequestSecurityTokenResponse in WIF

When you’re working with WIF and WSTrustChannelFactory when you call the Issue operation, you can also request that a RequestSecurityTokenResponse as an out parameter.

However, what can you do with that object?  Well, you could keep it around and use it for subsequent calls with the extension method CreateChannelWithIssuedToken – or can you?

public static T CreateChannelWithIssuedToken<T>(this ChannelFactory<T> factory, SecurityToken issuedToken);

 

As you can see from the method signature it takes a SecurityToken – but that’s not present on the RequestSecurityTokenResponse class.

However, you can through a little magic get a GenericXmlSecurityToken by means of the following set of extension methods below – just call

rstr.GetSecurityTokenFromResponse() – and you’ll get a GenericXmlSecurityToken as a return.

public static class TokenHelper
{


    /// <summary>
    /// Takes a RequestSecurityTokenResponse, pulls out the GenericXmlSecurityToken usable for further WS-Trust calls
    /// </summary>
    /// <param name="rstr"></param>
    /// <returns></returns>
    public static GenericXmlSecurityToken GetSecurityTokenFromResponse(this RequestSecurityTokenResponse rstr)
    {
        var lifeTime = rstr.Lifetime;
        var appliesTo = rstr.AppliesTo.Uri;
        var tokenXml = rstr.GetSerializedTokenFromResponse();
        var token = GetTokenFromSerializedToken(tokenXml, appliesTo, lifeTime);
        return token;
    }

    /// <summary>
    /// Provides a token as an XML string.
    /// </summary>
    /// <param name="rstr"></param>
    /// <returns></returns>
    public static string GetSerializedTokenFromResponse(this RequestSecurityTokenResponse rstr)
    {
        var serializedRst = new WSFederationSerializer().GetResponseAsString(rstr, new WSTrustSerializationContext());
        return serializedRst;
    }

    /// <summary>
    /// Turns the XML representation of the token back into a GenericXmlSecurityToken.
    /// </summary>
    /// <param name="tokenAsXmlString"></param>
    /// <param name="appliesTo"></param>
    /// <param name="lifetime"></param>
    /// <returns></returns>
    public static GenericXmlSecurityToken GetTokenFromSerializedToken(this string tokenAsXmlString, Uri appliesTo, Lifetime lifetime)
    {
        RequestSecurityTokenResponse rstr2 = new WSFederationSerializer().CreateResponse(
        new SignInResponseMessage(appliesTo, tokenAsXmlString),
        new WSTrustSerializationContext());
        return new GenericXmlSecurityToken(
            rstr2.RequestedSecurityToken.SecurityTokenXml,
            new BinarySecretSecurityToken(
                rstr2.RequestedProofToken.ProtectedKey.GetKeyBytes()),
            lifetime.Created.HasValue ? lifetime.Created.Value : DateTime.MinValue,
            lifetime.Expires.HasValue ? lifetime.Expires.Value : DateTime.MaxValue,
            rstr2.RequestedAttachedReference,
            rstr2.RequestedUnattachedReference,
            null);
    }

}