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 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) =>
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))
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….