WSTrustChannelFactory and WSTrustChannel
If you are already familiar with Windows Communication Foundation (WCF), you know that 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 that is issued by the security token service (STS) behind the scenes and uses this token to authenticate to the service. The main limitation to this approach is that there is no visibility into the client’s communications with the server. WCF automatically generates the request security token (RST) to the STS based on the issued token parameters on the binding. This means that the client cannot vary the RST parameters per request, inspect the request security token response (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 that Windows® Identity Foundation (WIF) supports requires control over the RST at a level that WCF does not easily allow. Therefore, WIF adds features that give you more control over communication with the STS.
WIF supports the following federation scenarios:
Using a WCF client without any WIF dependencies to authenticate to a federated service
Enabling WIF on a WCF client to insert an ActAs or OnBehalfOf element into the RST to the STS
Using WIF alone to obtain a token from the STS and 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 STSs. This topic discusses the remaining two scenarios.
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, because 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 that is obtained out of band to the RST. The following code example shows how to take a token that represents the client (such as an X.509, username, or Security Assertion Markup Language (SAML) token) and attach it to the RST that is sent to the issuer.
IHelloService serviceChannel = channelFactory.CreateChannelActingAs<IHelloService>( clientSamlToken ); serviceChannel.Hello(“Hi!”);
WIF provides the following benefits:
The RST can be modified per channel; therefore, 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 makes an easy upgrade path possible 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 examine this in the third scenario.
For some advanced scenarios, enhancing a WCF client is not enough. Developers who use 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 classes to let the client communicate directly with a WS-Trust issuer. The WSTrustChannelFactory and WSTrustChannel classes enable strongly typed RST and RSTR objects to flow between the client and issuer, as shown in the following code example.
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 that is returned from the WSTrustChannel object is a
GenericXmlSecurityToken that contains all of the information that is necessary for authentication to a relying party. The following code example shows how to use this token.
IHelloService serviceChannel = channelFactory.CreateChannelWithIssuedToken<IHelloService>( token ); serviceChannel.Hello(“Hi!”);
The CreateChannelWithIssuedToken extension method on the
ChannelFactory object 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 that you obtained to authenticate to the relying party. This has the following benefits:
It gives you complete control over the token issuance process.
It supports ActAs / OnBehalfOf scenarios by directly setting these properties on the outgoing RST.
It enables dynamic client-side trust decisions to be made based on the contents of the RSTR.
It lets you cache and reuse the token that is returned from the Issue method.
WSTrustChannelFactory and WSTrustChannel allow for control of channel caching, fault, and recovery semantics according to WCF best practices.
For more information, see the Extensibility/WSTrustChannel sample in the location where you installed WIF.