I’ve implemented a custom ASP.NET session timeout control derived from a control by Kenneth Scott. It’s hosted by IIS7 in .NET 4.
Long story short, it’s a server control (implementing System.Web.UI.WebControls.WebControl) that I include in my site master page. The control is invisible, and starts a timer when a page is rendered. After X minutes have passed, a DIV is displayed telling the user their session is timing out, and offers them a button to click if they want to stay logged in.
Clicking the button just fires a standard postback to the server. It doesn’t perform any useful work on the server, except for resetting the sliding expiry for the session.
The timeout control is configured to kick in a minute before the session should expire. When it reaches 0, the session should also be expiring, and I redirect the user to the login page and notify them that they timed out due to inactivity.
It works great the majority of the time, but sometimes “doesn’t work”. The button still appeared to work to users, but after trying to click any other control on the site, they immediately get dumped to the login page (standard ASP.NET behaviour defined in web.config).
I added some logging statements to the click event handler and discovered that it’s not firing. My assumption here is that the client is sending a request to the server, but since the session is expired, my event handler never fires.
I’m confident my app pool isn’t getting recycled (it’s configured to recycle once daily, and no processes or sticky-fingered admins are editing files in the application directory). This failure is happening intermittently. We’re using Forms authentication.
My system.web section in web.config:
<sessionState mode="InProc" timeout="20" />
<authentication mode="Forms">
<forms path="/" loginUrl="Pages/LoginPage.aspx" protection="All" timeout="20" slidingExpiration="true" />
</authentication>
My workaround for the moment has been to increase our session and forms timeout to 30 minutes, and introduce a new configuration setting for the timeout, which still logs the user out after 20 minutes. That extra 10 minutes provides enough padding that my control works as expected.
I dislike the solution because it’s a workaround at best. I feel like I don’t understand the ASP.NET session timeout mechanism adequately (despite having read and reread the MSDN documentation). Can anyone explain the behaviour I’m seeing, or maybe point out any bad assumptions I’m making?
You could try to log any application-endings and the reason for ending, just to rule out it has anything to do with that. I always use this script for that (just put it in the global.asax):