Tuesday 31 October 2006

Cookie Timeout Problem

JeffI recently had a problem where for some reason my Cookies were timing out before the time I set in the forms timeout tag.

Background

ASP.NET 2.0 site with forms auth using Active Directory Membership provider and the ASP Login Control. IIS 6.0 with separate App Pool being run by a custom domain account.

Following in Web.Config:

<membership defaultProvider="MyADMembershipProvidor">
<providers>
<add name="MyADMembershipProvidor" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" enableSearchMethods="true" />
</providers>
</membership>

<authentication mode="Forms">
<forms name=".ADAuthCookie" timeout="50000000" slidingExpiration="true" loginUrl="FormsLogin.aspx" />
</authentication>

<sessionState timeout="30">
</sessionState>

Problem

Everything works fine so I could authenticate using forms auth on the site and this would use AD fine. However once I left the page idle for 20min I clicked on a link and would be redirected back to the login page to authenticate. This was the same problem for both persistent and non-persistent cookies.

Solution

After spending some time thinking I was going mad I created a simple test harness. I used this to play around with the forms timeout, session timeout and roles cookie timeout. If I used a forms timeout value that was less than 20min all would work as expected, however using a value greater than 20min would not work and after 20min I would still be required to log in again.

After about a day of debugging I finally tracked the problem down to the worker process shutting down after 20min idle time. This config setting is found in the properties of the worker process under performance. If I unchecked this everything worked as expected. So the issue is around the App Pool recycling.

I found this article about invalid viewstate after an App Pool recycling when the identity is not Network Service.

So a known ASP.NET bug is the decryption and validation keys used for encryption are not maintained between App Pool recycling if the identity is not Network Service. So any encryption performed using these keys will not be valid after the App Pool is recycled, this will include any encrypted cookies.

Finally I had found the problem - When the App Pool recycles the keys are not maintained and new ones are generated, this results in any encrypted cookies, including the forms auth cookie not being decrypted on any subsequent requests from the browser and they are discarded.

To resolve this I edited the machine.config with a static decryption and validation key using this console app.

Everything is working fine now :)

No comments: