Chris Simmons
Chris Simmons

Reputation: 7266

MachineKeySessionSecurityTokenHandler and the session token expiring between application restarts

In my MVC application, I am using forms authentication to authenticate the user and then System.IdentityModel.Services.SessionAuthenticationModule to persist the session.

While I'm not yet at the point where it's necessary, I did want to utilize System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler so that the application will live nicely on a web farm (as described by Dominick Baier here).

The problem I have is that, given the machineKey-based handling, I would expect that not only would the session be valid from server machine to machine, but should also survive application restarts. However, any time I either restart or rebuild the application, upon hitting the application in the browser, the cookie apparently becomes invalid and I get bounced to the authentication screen. Once authenticated again, everything is fine and the session remains. However, the next time the app restarts or is rebuilt, I'm forced to re-authenticate.

I'm sure this is an aspect of WIF that I'm not getting, but I just don't know where to turn from here. I'm not afraid of having to extend MachineKeySessionSecurityTokenHandler, but I'd like to make sure that I understand what's going on here before I proceed. I understand that the default SessionSecurityTokenHandler uses DPAPI in combination with some identifier from the app pool for its cryptography, so it makes sense that this would happen in that case, but the behavior in MachineKeySessionSecurityTokenHandler puzzles me. Is there still some identifier in the application that gets recreated on restart on which MachineKeySessionSecurityTokenHandler depends? Am I just missing a setting?

Here are the pertinent parts from my web.config:

<configSections>
  <section name="system.identityModel"
           type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>

...

<system.identityModel>
  <identityConfiguration>
    <securityTokenHandlers>
      <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </securityTokenHandlers>
  </identityConfiguration>
</system.identityModel>

...

<system.web>
  <machineKey compatibilityMode="Framework45"
              validationKey="E27893..."
              decryptionKey="ABC..." 
              validation="SHA1" decryption="AES" />
  <authentication mode="Forms">
  <forms loginUrl="~/Account/Login"
         timeout="10080" />
  </authentication>
</system.web>

...

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="SessionAuthenticationModule"
         type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </modules>
</system.webServer>

Upvotes: 7

Views: 4617

Answers (2)

Chris Simmons
Chris Simmons

Reputation: 7266

OK, this was my stupid fault. For reasons that are not pertinent here, I set the FedAuth cookie name to something non-standard (i.e. not "FedAuth"), like this:

FederatedAuthentication
  .FederationConfiguration
  .CookieHandler
  .Name = "SomeThingNotStandard";

The problem was I was setting it like this only at the moment that I issued the token on a successful login. Well, of course everything's gonna be fine because now the in-memory configuration is looking for "SomeThingNotStandard" as the cookie name. But, on an app restart, the configuration will be back to the default, looking for "FedAuth", not "SomeThingNotStandard". This forces the re-login, which upon success, re-configures the app and then everything seems fine.

So I put the code bit above in Application_Start() and it works fine across re-builds and re-starts.

Dumb move on my part.

Edit:

I moved this to configuration

<system.identityModel.services>
  <federationConfiguration>
    <cookieHandler
      name="SomeThingNotStandard" />
  </federationConfiguration>
</system.identityModel.services>

Upvotes: 0

leastprivilege
leastprivilege

Reputation: 18482

hm - if you are setting the machine key explicitly (like you seem to do) - I don't see a reason why this would not work. Maybe you are using other cookies, sessions etc that trigger the re-auth problem?

Upvotes: 2

Related Questions