Using Silverlight to Access WIF secured WCF Services (Part 2)

This was one of my most popular blog post in the recent time (please read it first to get the necessary background information). I thought I give this another shot with the new SL/WIF integration.

There are other ways to accomplish the below things, e.g. using the SL application service or passive identity providers. I am focusing here purely on the SL initiated active STS/RP communication scenario and the raw APIs.

Requesting Tokens from within Silverlight
In my old post I had to use a custom REST endpoint in StarterSTS to request a bearer token. With the new WSTrustChannel, it is now possible to talk to a standard WS-Trust 1.3 endpoint (like the one in StarterSTS or ADFS2).

var client = new WSTrustClient(
    new WSTrustBindingUsernameMixed(),
    new EndpointAddress(https://…/issue.svc/mixed/username”),
    new UsernameCredentials(“username”, “password”));

You then have to construct an RST. Basically you specify the key type (bearer or symmetric) and appliesTo value.

var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Symmetric)
{
    AppliesTo = new EndpointAddress(https://roadie/StarterRP/”)
};

The call to WSTrustClient.Issue returns an RSTR – which in turn contains the requested token and further key material. The identity kit also contains a token cache called TokenCache. You could use this class if you want to to store that token for further use.

client.IssueCompleted += (s, args) =>
{
    _cache.AddTokenToCache(“myRP”, args.Result);
};
 
client.IssueAsync(rst);

Using a Token to authenticate with a WCF Relying Party
Since Silverlight does not support issued token credentials, we must handcraft the SOAP security header. The identity kit includes the IssuedTokenHeader class for this purpose. The nice thing is, that this class supports symmetric proof keys as well as bearer tokens. But you still have to set this header manually on every call.

The identity kit includes its own wrapper to abstract away the header generation. I am using my own little helper here to make this process less disruptive.

public static class IssuedTokenHeaderExtensions
{
    public static void SendWithIssuedToken(this IContextChannel channel,
      RequestSecurityTokenResponse
rstr, Action action)
    {
        using (new OperationContextScope(channel))
        {
            OperationContext.Current.OutgoingMessageHeaders.Add(
              new IssuedTokenHeader(rstr));

           
action();
        }
    }
}

This allows calling a WCF service like this:

private void CallService()
{
    var factory = new ChannelFactory<StarterServiceContract>(“myRP”);
    var proxy = factory.CreateChannel();
    var channel = proxy as IContextChannel;
 
    channel.SendWithIssuedToken(_cache.GetTokenFromCache(“myRP”), () =>
        {
            proxy.BeginGetClaims(result => ShowClaims(proxy, result), null);
        });
}

The trick here again is, that the client stack is configured for no security at all, whereas the WCF service uses a federation binding (with SecureConversation turned off).

I think this is pretty cool and solves some of the problems I had in the past. If Silverlight would only support client certificate credentials….

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 )

Connecting to %s