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

Posted by Your DisplayName here! on Least Privilege See other posts from Least Privilege or by Your DisplayName here!
Published on Tue, 22 Jun 2010 06:45:17 GMT Indexed on 2010/12/06 17:00 UTC
Read the original article Hit count: 228

Filed under:

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

© Least Privilege or respective owner

Related posts about IdentityModel