A more elegant way of embedding a SOAP security header in Silverlight 4

Posted by Your DisplayName here! on Least Privilege See other posts from Least Privilege or by Your DisplayName here!
Published on Fri, 14 May 2010 05:01:54 GMT Indexed on 2010/12/06 17:00 UTC
Read the original article Hit count: 278

Filed under:

The current situation with Silverlight is, that there is no support for the WCF federation binding. This means that all security token related interactions have to be done manually.

Requesting the token from an STS is not really the bad part, sending it along with outgoing SOAP messages is what’s a little annoying. So far you had to wrap all calls on the channel in an OperationContextScope wrapping an IContextChannel. This “programming model” was a little disruptive (in addition to all the async stuff that you are forced to do).

It seems that starting with SL4 there is more support for traditional WCF extensibility points – especially IEndpointBehavior, IClientMessageInspector. I never read somewhere that these are new features in SL4 – but I am pretty sure they did not exist in SL3.

With the above mentioned interfaces at my disposal, I thought I have another go at embedding a security header – and yeah – I managed to make the code much prettier (and much less bizarre). Here’s the code for the behavior/inspector:

public class IssuedTokenHeaderInspector : IClientMessageInspector
{
    RequestSecurityTokenResponse _rstr;
 
    public IssuedTokenHeaderInspector(RequestSecurityTokenResponse rstr)
    {
        _rstr = rstr;
    }
 
    public void AfterReceiveReply(ref Message reply, object correlationState)
    { }
 
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        request.Headers.Add(new IssuedTokenHeader(_rstr));
        
        return null;
    }
}
 

public class IssuedTokenHeaderBehavior : IEndpointBehavior
{
    RequestSecurityTokenResponse _rstr;
 
    public IssuedTokenHeaderBehavior(RequestSecurityTokenResponse rstr)
    {
        if (rstr == null)
        {
            throw new ArgumentNullException();
        }
 
        _rstr = rstr;
    }
 
    public void ApplyClientBehavior(
      ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new IssuedTokenHeaderInspector(_rstr));
    }
 
    // rest omitted
}

This allows to set up a proxy with an issued token header and you don’t have to worry anymore with embedding the header manually with every call:

var client = GetWSTrustClient();
 
var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Symmetric)
{
    AppliesTo = new EndpointAddress("https://rp/")
};
 
client.IssueCompleted += (s, args) =>
{
    _proxy = new StarterServiceContractClient();
    _proxy.Endpoint.Behaviors.Add(new IssuedTokenHeaderBehavior(args.Result));
 
};
 
client.IssueAsync(rst);

Since SL4 also support the IExtension<T> interface, you can also combine this with Nicholas Allen’s AutoHeaderExtension.

© Least Privilege or respective owner

Related posts about IdentityModel