WIF, ADFS 2 and WCF–Part 5: Service Client (more Flexibility with WSTrustChannelFactory)
- by Your DisplayName here!
See the previous posts
first.
WIF includes an API to manually request tokens from a token service. This gives you
more control over the request and more flexibility since you can use your own token
caching scheme instead of being bound to the channel object lifetime.
The API is straightforward. You first request a token from the STS and then use that
token to create a channel to the relying party service. I’d recommend using the WS-Trust
bindings that ship with WIF to talk to ADFS 2 – they are pre-configured to match the
binding configuration of the ADFS 2 endpoints.
The following code requests a token for a WCF service from ADFS 2:
private static SecurityToken GetToken()
{
// Windows authentication over
transport security
var factory
= new WSTrustChannelFactory(
new WindowsWSTrustBinding(SecurityMode.Transport),
stsEndpoint);
factory.TrustVersion = TrustVersion.WSTrust13;
var rst
= new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointAddress(svcEndpoint),
KeyType = KeyTypes.Symmetric
};
var channel
= factory.CreateChannel();
return channel.Issue(rst);
}
Afterwards, the returned token can be used to create a channel to the service. Again
WIF has some helper methods here that make this very easy:
private static void CallService(SecurityToken token)
{
// create binding and turn off
sessions
var binding
= new WS2007FederationHttpBinding(
WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
// create factory and enable
WIF plumbing
var factory
= new ChannelFactory<IService>(binding, new EndpointAddress(svcEndpoint));
factory.ConfigureChannelFactory<IService>();
// turn off CardSpace - we already
have the token
factory.Credentials.SupportInteractive = false;
var channel
= factory.CreateChannelWithIssuedToken<IService>(token);
channel.GetClaims().ForEach(c =>
Console.WriteLine("{0}\n
{1}\n {2} ({3})\n",
c.ClaimType,
c.Value,
c.Issuer,
c.OriginalIssuer));
}
Why is this approach more flexible? Well – some don’t like the configuration voodoo.
That’s a valid reason for using the manual approach. You also get more control over
the token request itself since you have full control over the RST message that gets
send to the STS.
One common parameter that you may want to set yourself is the appliesTo value.
When you use the automatic token support in the WCF federation binding, the appliesTo is
always the physical service address. This means in turn that this address will be
used as the audience URI value in the SAML token. Well – this in turn means that when
you have an application that consists of multiple services, you always have to configure
all physical endpoint URLs in ADFS 2 and in the WIF configuration of the service(s).
Having control over the appliesTo allows you to use more symbolic realm names, e.g.
the base address or a completely logical name. Since the URL is never de-referenced
you have some degree of freedom here.
In the next post we will look at the necessary code to request multiple tokens in
a call chain. This is a common scenario when you first have to acquire a token from
an identity provider and have to send that on to a federation gateway or Resource
STS.
Stay tuned.