I recently ran into a problem on one of our websites where users’ authentication was timing out before the amount of time I had set in the configuration.  I was using ASP.NET forms authentication with the timeout set to 30 minutes and sliding expiration set to true.  After some investigation this turned out to be a two part problem.

This first cause I found was that the sliding expiration functionality for forms authentication isn’t exactly intuitive.  When sliding expiration is turned on, each time a web page is requested, the user’s authentication cookie timeout is supposed to be updated to the expire in X minutes from the time of the page request.  However, even though you set a timeout of X minutes it is perfectly normal for a users authentication ticket to expire before that time limit due to the sliding expiration is implemented in the .NET framework.  From the MSDN .NET Framework Reference:

“If the SlidingExpiration attribute is true, the timeout attribute is a sliding value, expiring at the specified number of minutes after the time the last request was received. To prevent compromised performance, and to avoid multiple browser warnings for users that have cookie warnings turned on, the cookie is updated when more than half the specified time has elapsed. This might result in a loss of precision.”

Basically, if the timeout is set to 30 minutes then the expiration time of the authentication cookie is only updated if 15 minutes have passed when a request is made. [more] If a user signed in at 8:00 and requested a page at 8:14 you would think that their authentication would timeout 30 minutes after their last request at 8:44, but instead it would actually timeout at 8:30.  So if you want the timeout to for sure be at least a certain number of minutes you can increase the timeout to twice the desired time, or write your own code to refresh the cookie after each page request.

The second cause of the problem that I found was that the settings on the Application Pool in IIS was causing the ASP.NET worker process to be recycled after a number of minutes and shutdown after 20 of being idle.  I changed the worker process to recycle at a set time during off peak hours instead of after a number of minutes had passed. I also increased the number of idle minutes before the worker process would shutdown.  I included screen shots of the settings below.