MachineKey based Session Protection for WIF

When using the session facility in WIF (e.g. in ASP.NET with the SessionAuthenticationModule), the session token must be protected somehow. By default WIF uses the Windows built-in DPAPI mechanism.

While DPAPI is easy to use in single-server scenarios it has some shortcomings:

  • DPAPI requires the IIS user profile to be loaded. This can be a problem when you don’t have admin access to IIS (e.g. in hosted scenarios like Azure Web Sites [here]).
  • DPAPI only works for non load-balanced scenarios since the DPAPI key is machine specific.

One workaround was to provide a different implementation of the protection pipeline, e.g. using X.509 certificates. This wasn’t horribly hard to do but requires some custom code and setup.

In .NET 4.5 there’s a new out-of-the-box protection mechanism using the ASP.NET machine key which may be exactly the right option (for certain scenarios). But since most of you are not running .NET 4.5 – I quickly wrote an implementation of that token handler for .NET 4.0 and made it available as part of Thinktecture.IdentityModel.

To replace the built-in session token handler with the machine key based one, do this:

  1. Make sure your machine keys are synced when using a web farm.
  2. Download Thinktecture.IdentityModel (either as source code from github, or using Nuget).
  3. Replace the session handler in WIF config:

<securityTokenHandlers>

  <remove type=Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
/>

  <add type=Thinktecture.IdentityModel.Web.MachineKeySessionSecurityTokenHandler, Thinktecture.IdentityModel />

</securityTokenHandlers>

 

HTH

This entry was posted in ASP.NET, IdentityModel. Bookmark the permalink.

21 Responses to MachineKey based Session Protection for WIF

  1. Cleber says:

    Hi! I tried to use MachineKeySessionSecurityTokenHandler in my solution but the Decode Method throws HttpExceprion (Error Validating Data). For test purpose a I’m debuging the solution on a local IIS. Maybe it work just on Azure or I’m doing something wrong?

  2. Pingback: Windows Azure and Cloud Computing Posts for 8/6/2012+ - Windows Azure Blog

  3. JMan says:

    Dominic – Without loading a certificate, is the cookie value still protected?

  4. Hi, Just a very quick note to say a huge thank you for this post!

  5. Matt Davis says:

    Fantastic, thought my STS was my silver bullet until I tried to use it on Azure.

  6. David Williams says:

    Thanks Dominick. I am sort of amazed that ACS rolled out on Azure without a solution for this.

  7. Adam Karl says:

    This was a massive improvement however there are still scenarios where we see problems de-crypting tokens. The scenarios are difficult to reproduce but the end result is that a token/cookie a user was using yesterday is no longer valid today. When this happens we see uncaught Cryptographic and/or Argument Exceptions from the MachineKeyTransform. I’ve added exception trapping around these scenarios in my implementation of the SessionAuthenticationModule and in the MachineKeyTransform. Basically, when I encounter Crypto exceptions, I log the user out (kill their cookies in my case) and send them back through the STS server to re-issue their session.

  8. @Adam – but also have expiration times – might that be the reason the token from today is expired tomorrow/invalid tomorrow?

  9. …and have a fixed machine key?

    • akarl16 says:

      Fixed machine key and the cookies are issued as session cookies so as long as the browser is open they remain. Its difficult to tell what changed in the cookie format when this happens but in my latest occurrence I also noticed that when it errored I had 2 cookies, FedAuth and FedAuth1. After I forced a re-issuance of tokens I had 3 cookies. I wouldn’t have expected this to be a problem, its just an odd coincidence that the two things occurred at the same time.

    • akarl16 says:

      Maybe we mean different things. I am using http://en.wikipedia.org/wiki/HTTP_cookie#Session_cookie which in the definition has no expiration. Is there something in the token contents that would expire? If so that would explain the problem.

  10. jIn says:

    How can I have a fixed machine key?
    Do I have to change somewhere in config? to my preferred key?

  11. Hi Dominick, thanks for the post. I’m trying to use this code but I’m receiving the following error, I cannot realize whats going on. Do you know what the problem might be. ?
    Error:
    Exception of type ‘System.ArgumentException’ was thrown.
    Parameter name: encodedData

    StackTrace:
    at System.Web.Security.MachineKey.Decode(String encodedData, MachineKeyProtection protectionOption)
    at Thinktecture.IdentityModel.Web.MachineKeyCookieTransform.Decode(Byte[] encoded) in c:\projects\ationet\development\ationet\Thinktecture.IdentityModel\Web\MachineKeyCookieTransform.cs:line 16
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound)
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver)
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie)
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken)
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs)
    at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    • No – not sure. First time I see this. You have to debug.

      • Julien says:

        I also had the same issue…it happened when I replaced the default SessionSecurityTokenHandler with the MachineKeySessionSecurityTokenHandler and it turned out to be because the session cookies were not cleared and therefore were encrypted the old way. Just clearing the cookies fix the issue for me.
        - Julien

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s