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:
- 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, 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:
- 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 allows dynamic client-side trust decisions to be made based
on the contents of the RSTR.
- The token returned from Issue can be cached and
reused.
- 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.