For developers who are already familiar with WCF, a WCF client is already federation aware. By configuring a WCF client with a WSFederationHttpBinding or similar custom binding, you can enable federated authentication to a service.

WCF obtains the token issued by the STS behind the scenes, and uses this token to authenticate to the service. The main limitation to this approach is that there’s no visibility into the client’s communications with the server. WCF automatically generates the RST to the STS based on the issued token parameters on the binding. This means that the client can’t vary the RST parameters per request, inspect the RSTR to get information such as display claims, or cache the token for future use.

Currently, the WCF client is suitable for basic federation scenarios. However, one of the major scenarios supported by WIF requires control over the RST at a level that WCF does not easily allow. So WIF adds features that give the developer more control over communication with the STS.

WIF supports the following federation scenarios:

  1. Using a WCF client without any WIF dependencies to authenticate to a federated service.

  2. Enabling WIF on a WCF client to insert an ActAs or OnBehalfOf element into the RST to the STS.

  3. Using WIF alone, obtain a token from the STS. Then enable a WCF client to authenticate with this token.

The first scenario is self-explanatory. Existing WCF clients will continue to work with WIF relying parties and STSes. This topic discusses the remaining two scenarios.

Enhancing an Existing WCF Client with ActAs / OnBehalfOf

In a typical identity delegation scenario, a client calls a middle-tier service which then calls a back-end service. The middle-tier service acts as, or acts on behalf of, the client. (For more information, see the section “ActAs and OnBehalfOf” in Frequently Asked Questions.) This information is conveyed to a WS-Trust issuer using the ActAs and OnBehalfOf token elements in the RST.

WCF exposes an extensibility point on the binding that allows arbitrary XML elements to be added to the RST. However, since the extensibility point is tied to the binding, scenarios that require the RST contents to vary per call must re-create the client for every call, which decreases performance. WIF uses extension methods on the ChannelFactory class to allow developers to attach any token obtained out of band to the RST. The following code shows how to take a token that represents the client (such as an X.509, username, or SAML token) and attach it to the RST sent to the issuer.

  Copy Code
IHelloService serviceChannel = channelFactory.CreateChannelActingAs<IHelloService>( clientSamlToken );
serviceChannel.Hello(“Hi!”);

WIF provides the following benefits:

  • The RST can be modified per channel, so middle-tier services do not have to re-create the channel factory for each client, which improves performance.

  • This works with existing WCF clients, which allows an easy upgrade path for existing WCF middle-tier services that want to enable identity delegation semantics.

However, there is still no visibility into the client’s communication with the STS. We’ll look at this in the third scenario.

Communicating Directly with an Issuer and Using the Issued Token to Authenticate

For some advanced scenarios, enhancing a WCF client is not enough. Developers using only WCF typically use Message In / Message Out contracts and handle client-side parsing of the issuer response manually.

WIF introduces the WSTrustChannelFactory and WSTrustChannel to let the client communicate directly with a WS-Trust issuer. WSTrustChannelFactory and WSTrustChannel allow strongly-typed RST and RSTR objects to flow between the client and issuer. The following code sample shows this:

  Copy Code
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory( stsBinding, stsAddress );
WSTrustChannel channel = (WSTrustChannel) trustChannelFactory.CreateChannel();
RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue);
rst.AppliesTo = new EndpointAddress(serviceAddress);
RequestSecurityTokenResponse rstr = null;
SecurityToken token = channel.Issue(rst, out rstr);

Note that the out parameter on the Issue method allows access to the RSTR for client-side inspection.

So far, we’ve only seen how to obtain a token. The token returned from the WSTrustChannel is a GenericXmlSecurityToken that contains all of the information needed for authentication to a relying party. The following code sample shows how to use this token:

  Copy Code
IHelloService serviceChannel = channelFactory.CreateChannelWithIssuedToken<IHelloService>( token ); serviceChannel.Hello(“Hi!”);

The CreateChannelWithIssuedToken extension method on the ChannelFactory indicates to WIF that you have obtained a token out of band, and that it should stop the normal WCF call to the issuer and instead use the token you obtained to authenticate to the relying party. This has the following benefits:

  1. It gives you complete control over the token issuance process.

  2. It supports ActAs / OnBehalfOf scenarios by directly setting these properties on the outgoing RST.

  3. It allows dynamic client-side trust decisions to be made based on the contents of the RSTR.

  4. The token returned from Issue can be cached and reused.

  5. WSTrustChannelFactory and WSTrustChannel allow for control of channel caching, fault, and recovery semantics in line with WCF best practices.

For more information, see the Extensibility/WSTrustChannel sample in the location where you installed WIF.