woensdag 31 juli 2013

Call WCF service with ADFS token

How can we configure a WCF client to call an ADFS-secured WCF service? In this blog I'll show you how to do it with code only, no xml-configuration needed.

The are only two steps to take:

1. Get a securityToken from ADFS
2. Create a WCF channel to the WCF service, using the securityToken.

Create the WCF client

To get started, let's create a console application that will be the client:

internal class Program
   private static void Main()
      var stsEndpoint =
      var clientCertificateThumbprint = "[put the thumbprint here]";
      var svcEndpoint = "https://myDomain/myService.svc";

      var token = GetToken(stsEndpoint, svcEndpoint);

      var channel = CreateChannel<IMyService>(token,



How to get a secured token from ADFS?

The GetToken() method looks like this:

private static SecurityToken GetToken(string stsEndpoint,
                                      string svcEndpoint,
                                      string thumbprint)
   var binding = new
   var factory = new WSTrustChannelFactory(bindingstsEndpoint)
                               TrustVersion = TrustVersion.WSTrust13


   var rst = new RequestSecurityToken

                         RequestType = WSTrust13Constants.RequestTypes.Issue,
                         AppliesTo = new EndpointAddress(svcEndpoint),
                         KeyType = WSTrust13Constants.KeyTypes.Symmetric

   var channel = factory.CreateChannel();

   var token = channel.Issue(rst);

   return token;


Please note that I'm using a client certificate, and not Username/Password to authenticate.

With the token, the secured channel can be created, like this:

private static T CreateChannel<T>(SecurityToken token, string svcEndpoint) where T : class
   var binding = new WS2007FederationHttpBinding(
   binding.Security.Message.EstablishSecurityContext = true;
   binding.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;

   var factory = new ChannelFactory<T>(binding, svcEndpoint);

   // Turn Cardspace off
   factory.Credentials.SupportInteractive = false;

   var channel = factory.CreateChannelWithIssuedToken(token);
   return channel;