Caching STS Security Token with an Active Web Client

A common scenario when using an STS (Being ADFS or Custom STS) is the requirement to cache the security token to be used repeatedly with the requests to WCF services to authenticate the calls. This is usually easy in desktop applications when most people go and cache the entire service proxy object in some global variable!

The recommended approach is to cache the security token itself and use it later on which has the following advantages…

  • You can use the same token with different WCF services that accept the token
  • You can renew the token before it expires

 

I’ve created a small sample with Active Web client with one page that first: caches the token, then use it to make the service calls.

The following method can be used to cache the token…

CacheToken()

{

// First, create binding to the service. The below URL is the name of the binding

// It is important to note that this will cause the next calls to use v1.3. If you want to use Feb 2005 standards, use WSHttpBinding, not 2007

WS2007HttpBinding wsf =new WS2007HttpBinding(@”https://vs2010.contoso.com/ATMServicesSTS/Service1.svc/IWSTrust13″);

// Now create a WS trust factory that will be used to create the communication channel with the STS

WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(wsf,new EndpointAddress(@”https://vs2010.contoso.com/ATMServicesSTS/Service1.svc/IWSTrust13″));

// I use User Name/Password for security

trustChannelFactory.Credentials.UserName.UserName =“My User Name”;

trustChannelFactory.Credentials.UserName.Password =“My Password”;

// just to make sure no certificates involved

      trustChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

      trustChannelFactory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;

// specifiy the trust version

      trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;

// Now create the cannel

WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();

// Specify the request parameters including Audience URI and lifetime

RequestSecurityToken rst =new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue){Lifetime =new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(5))};

rst.AppliesTo = new EndpointAddress(@”https://vs2010.contoso.com/ATMServices/”);

RequestSecurityTokenResponse rstr =null;

// Get the token

SecurityToken token = channel.Issue(rst,out rstr);

// Cache it in the session

Session[“Token”] = token;

}

Now, Use the token…

// Create the proxy object

ActiveClient.ATMServices.ServiceClient sc =new ActiveClient.ATMServices.ServiceClient();

// Configure the channel factory

sc.ChannelFactory.ConfigureChannelFactory<ActiveClient.ATMServices.IService>();

// Create the channel with the issued token

ActiveClient.ATMServices.IService serviceChannel = sc.ChannelFactory.CreateChannelWithIssuedToken<ActiveClient.ATMServices.IService>((SecurityToken)Session[“Token”]);

// call the service method

txtReturn.Text = serviceChannel.GetData(50);

 

Remember to add references to WIF to your project.

 

 Happy Coding:)

 

Update 20/1/2012: Sample project added as an attachement.

 

ActiveWebClient.zip