Modifying the SL/WIF Integration Bits to support Issued Token Credentials

The SL/WIF integration code that ships with the Identity Training Kit only supports Windows and UserName credentials to request tokens from an STS. This is fine for simple single STS scenarios (like a single IdP). But the more common pattern for claims/token based systems is to split the STS roles into an IdP and a Resource STS (or whatever you wanna call it).

In this case, the 2nd leg requires to present the issued token from the 1st leg – this is not directly supported by the bits. But they can be easily modified to accomplish this.

The Credential
Fist we need a class that represents an issued token credential. Here we store the RSTR that got returned from the client to IdP request:

public class IssuedTokenCredentials : IRequestCredentials
{
    public string IssuedToken { get; set; }
    public RequestSecurityTokenResponse RSTR { get; set; }

    public IssuedTokenCredentials(RequestSecurityTokenResponse rstr)
    {
        RSTR = rstr;
        IssuedToken = rstr.RequestedSecurityToken.RawToken;
    }
}

The Binding
Next we need a binding to be used with issued token credential requests. This assumes you have an STS endpoint for mixed mode security with SecureConversation turned off.

public class WSTrustBindingIssuedTokenMixed : WSTrustBinding
{
    public WSTrustBindingIssuedTokenMixed()
    {
        this.Elements.Add( new HttpsTransportBindingElement() );
    }
}

WSTrustClient
The last step is to make some modifications to WSTrustClient to make it issued token aware. In the constructor you have to check for the credential type, and if it is an issued token, store it away.

private RequestSecurityTokenResponse _rstr;
public WSTrustClient( Binding binding, EndpointAddress remoteAddress, 
IRequestCredentials credentials )
    : base( binding, remoteAddress )
{
    if ( null == credentials )
    {
        throw new ArgumentNullException( "credentials" );
    }

    if (credentials is UsernameCredentials)
    {
        UsernameCredentials usernname = credentials as UsernameCredentials;
        base.ChannelFactory.Credentials.UserName.UserName = usernname.Username;
        base.ChannelFactory.Credentials.UserName.Password = usernname.Password;
    }
    else if (credentials is IssuedTokenCredentials)
    {
        var issuedToken = credentials as IssuedTokenCredentials;
        _rstr = issuedToken.RSTR;
    }
    else if (credentials is WindowsCredentials)
    { }
    else
    {
        throw new ArgumentOutOfRangeException("credentials", "type was not expected");
    }
}

Next – when WSTrustClient constructs the RST message to the STS, the issued token header must be embedded when needed:

private Message BuildRequestAsMessage( RequestSecurityToken request )
{
    var message = Message.CreateMessage(
base.Endpoint.Binding.MessageVersion ?? MessageVersion.Default,
      IssueAction,
      (BodyWriter) new WSTrustRequestBodyWriter( request ) );

    if (_rstr != null)
    {
        message.Headers.Add(new IssuedTokenHeader(_rstr));
    }

    return message;
}

HTH

This entry was posted in IdentityModel. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s