ASP.NET: How to Detect Authentication Timeout
I've seen multiple articles like this one that explain how to detect that a user's session has timed out. And for clarity's sake, these articles are referring to the timeout value defined by this web.config line:
<sessionState mode="InProc" cookieless="UseDeviceProfile" timeout="120" />
Not to get into that method too much, but this involves checking that Session.IsNewSession is true and that a session cookie already exists. But I haven't seen any articles on how to detect authentication timeout -- 开发者_运维技巧the one defined by this web.config line:
<authentication mode="Forms">
<forms loginUrl="~/Home/Customer" timeout="60" name=".ASPXAUTH" requireSSL="false" slidingExpiration="true" defaultUrl="~/Home/Index" cookieless="UseDeviceProfile" enableCrossAppRedirects="false"/>
</authentication>
Multiple articles online, including this SO post, have said that your Session timeout value should generally be double your Authentication timeout value. So right now, as above, my Session is 120 and my Authentication is 60. This means that I'll never get in a situation where the Session has timed out, but the user is still Authenticated; if the user ever times out, it will be due to Authentication, not Session.
So, like everyone else, I'm interested in how to report to the user that their session has timed out (but really it'll be due to the Authentication timeout). Does anyone know of a way to accomplish this, or any resources online that can point me to a solution?
This is probably not the optimum approach, but here's something I thought of.
On login, record a timestamp in the session marking when the user logged in. On each subsequent request (maybe in the global.asax BeginRequest?), compare this timestamp to the current time, and match this up with the authentication timeout (Scott Hanselman explains how to read it here).
That's my "off top of my head" thought anyhow...
I would leverage the http pipeline early in the request and send an apporpriate response.
My source for answering such questions is:
Professional ASP.NET 2.0 Security, Membership, and Role Management
An HTTP module might do the trick:
Web.config:
<configuration>
<system.web>
<httpModules>
<add name="MyAuthModule" type="MyAssembly.Security.MyAuthModule, MyAssembly"/>
...
The Actual HTTP Module:
/// <summary>
/// A module for detecting invalid authentication
/// </summary>
/// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
public class MyAuthModule : IHttpModule
{
#region IHttpModule Members
void IHttpModule.Dispose() { }
void IHttpModule.Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
}
#endregion
/// <summary>
/// Inspect the auth request...
/// </summary>
/// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
private void context_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication a = (HttpApplication)sender;
HttpContext context = a.Context;
// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = context.Request.Cookies[cookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// check if previously authenticated session is now dead
if (authTicket != null && authTicket.expired)
{
// send them a Response indicating that they've expired.
}
}
}
}
Good luck!
When you log the user, you could drop a cookie on the user's machine indicating that they had a session. When the user reaches the login page (because if their session expired, their login must also have), check to see if the user has that cookie and if they have any of the session keys you expect them to have (if this proves difficult, just set a session variable when they log in). if they have the cookie, but none of the session keys, then their session expired.
精彩评论