In this part we will finally build a client for our federated service.
There are basically two ways to accomplish this. You can use the WCF built-in tooling to generate client and configuration via the service metadata (aka ‘Add Service Reference’). This requires no WIF on the client side. Another approach would be to use WIF’s WSTrustChannelFactory to manually talk to the ADFS 2 WS-Trust endpoints. This option gives you more flexibility, but is slightly more code to write. You also need WIF on the client which implies that you need to run on a WIF supported operating system – this rules out e.g. Windows XP clients.
We’ll start with the metadata way. You simply create a new client project (e.g. a console app) – call ‘Add Service Reference’ and point the dialog to your service endpoint. What will happen then is, that VS will contact your service and read its metadata. Inside there is also a link to the metadata endpoint of ADFS 2. This one will be contacted next to find out which WS-Trust endpoints are available. The end result will be a client side proxy and a configuration file. Let’s first write some code to call the service and then have a closer look at the config file.
var proxy = new ServiceClient();
proxy.GetClaims().ForEach(c =>
Console.WriteLine(“{0}n {1}n {2} ({3})n”,
c.ClaimType,
c.Value,
c.Issuer,
c.OriginalIssuer));
That’s all. The magic is happening in the configuration file.
When you in inspect app.config, you can see the following general configuration hierarchy:
- <client /> element with service endpoint information
- federation binding and configuration containing
- ADFS 2 endpoint 1 (with binding and configuration)
- ADFS 2 endpoint n (with binding and configuration)
(where ADFS 2 endpoint 1…n are the endpoints I talked about in part 1)
You will see a number of <issuer /> elements in the binding configuration where simply the first endpoint from the ADFS 2 metadata becomes the default endpoint and all other endpoints and their configuration are commented out. You now need to find the endpoint you want to use (based on trust version, credential type and security mode) and replace that with the default endpoint. That’s it.
When you call the WCF proxy, it will inspect configuration, then first contact the selected ADFS 2 endpoint to request a token. This token will then be used to authenticate against the service.
In the next post I will show you the more manual approach using the WIF APIs.
Hello,
thanks for these posts. I’m trying to configure WCF service with ADFS authentication. But my dev machine is outside client’s domain in which AD FS server is sitting. My machine therefore doesn’t see AD FS server. As I understand I can’t use the Add Service Reference way?
nope
Thanks for answering. I have one more question which I cannot find answer to anywhere. But the question seems simple… If I have web application outside the domain (which users authenticate to using ADFS from inside the domain), and WCF services are hosted in this application. Can I authenticate to them using ADFS like you describe, but not from desktop client inside the domain but from the web application? So user with his browser is inside the domain, he authenticates with the web application by being redirected to the AD FS server, and then an .aspx page in this web application tries to use one of it’s WCF services. On my test environment I constantly get the error that remote host could not be found while trying to reach AD FS server (which is quite reasonable as the web application can’t see inside the domain).
All examples that I found so far are using either console app, or WPF etc as a client, or web application is also inside the domain so it sees the AD FS server. I think that my scenario is quite common, so probably I’m doing something fundamentally wrong here…
If you want to use ADFS to authenticate with the WCF service – it must be reachable from the web server. Many people use an ADFS proxy to extend the reach to e.g. a DMZ.
Thanks, I knew I was missing something crucial!