In the previous article we understood WS-Trust and WS-Federation and saw briefly how they are used with WCF. Now let’s see an example of how to configure a WCF service to delegate authentication to an STS.
Here I will configure my WCF service to delegate authentication to ADFS. The federation service namespace is “fs1.lab1.local”.
The following section sets the service certificate; the one that will be used to access the service over SSL (this is a self-signed certificate using makecert):
The binding configuration is shown below:
- The ws2007FederationHttpBinding supports WS-Trust and indicates that the service is expecting issued tokens.
- “TransportWithMessageCredentials” mean that we will passing around a token issued by an STS and security will be done via transport (SSL)
- Notice that we are using “BearerKey” here to indicate bearer tokens – it’s the less secure approach – but to simplify things for now in order not to introduce encryption requirements. Please review my previous WS-Security in WCF article to understand what are bearer tokens and what are the other options.
- “https://fs1.lab1.local/adfs/services/trust/13/usernamemixed” is the ADFS endpoint issuing tokens. There are multiple ADFS endpoints; this one issues tokens based on username/password authentication
- While “https://fs1.lab1.local/adfs/services/trust/mex” is the metadata endpoint
The core identity configuration goes under <system.identityModel>:
- The audience URI points to the service URL itself – this is the audience accepting the issued token.
- I am using the default issuer name registry (which maintains a list of issuers that are trusted by the relying party (RP) application)
- And i’m using the certificate thumbprint that will be used to verify the token signed by the STS (ADFS in this case). Of course this means that I have the public key of the certificate stored in my local store (and because it’s self signed it’s actually stored in the trusted CAs store)
That’s it for the service.
Client Using Configuration
First let’s see how you would configure a client to call the service through configuration:
As I explained in the previous article, we have two bindings:
- the ws2007HttpBinding wraps the WS-Security stuff. It is used to establish trust and secure messaging in order to issue the token.
- the ws2007FederationHttpBinding verifies the token and transforms it into a set of claims to be consumed by the service
Client Using Code
Sometimes we want more flexibility at our clients. We can explicitly call the STS to get the token, then pass the token to the service (steps which are done implicitly by WCF when using configuration). This is available to us via the “WSTrustChannelFactory” and the “WSTrustChannel” classes:
You can always step in and see what the token looks like:
The above code asks the STS to issue the token. Then using the below code you pass this token to the WCF service; if authenticated (and authorized – which is not discussed here) then you will be granted access:
It’s always interesting to enable tracing and see exactly what’s happening. You will understand great deal about how WCF is managing all the WS-Security and WS-Trust complexities. Not to mention of course that this MUST be your number 1 tool for troubleshooting errors; especially in the WS-* world were so much can go wrong: