8

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?

Community
  • 1
  • 1
Matt
  • 23,363
  • 39
  • 111
  • 152
  • Sorry, I'm a little confused. Is your problem how to detect the timeout, or how to report to the user that you've detected a timeout? – Ender Dec 09 '10 at 19:36
  • 1
    Reporting to the user should be straightforward once I know how to detect the timeout. I'm much more interested in how to detect the timeout than I am on how to report it. – Matt Dec 09 '10 at 19:42
  • I've struggled with this as well, since it's impossible to tell the different between an authentication failure or an authorization failure when the user is redirected to the login page. - http://stackoverflow.com/questions/1352501/detecting-forms-authentication-timeout-in-login-page – RyanW Aug 29 '11 at 14:39

3 Answers3

1

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...

Ender
  • 14,995
  • 8
  • 36
  • 51
1

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!

Brett
  • 8,575
  • 5
  • 38
  • 51
  • This looks very promising, and I tried it out. But it looks like, when my authentication period has expired, the "authCookie" is null in the code you've provided. Which makes me wonder how the "Expired" property would ever be true. Is there a way authCookie could be not null and still expired? Thanks. – Matt Dec 20 '10 at 03:41
  • @mega-matt: Very likely to be true. But does it matter for your purpose? Absence of the auth cookie early in the pipeline would also identify an expired auth "session" -- the browser won't return expired cookies. I was using the code for another purpose, but I've found that leveraging the HTTP Pipleline is a very powerful technique... – Brett Dec 20 '10 at 17:15
  • You're right, the absence of the auth cookie would typically mean that the authentication period has expired. But what about before the cookie is ever created? The code you provided will run prior to the cookie ever being established. So as the user is going about logging in (auth cookie not created), this code will run and continue to redirect them to the login page (which is what I had planned to do in expired auth situation). So, yes, an absence of the auth cookie *could* mean the auth session has expired, but it also could mean the cookie just hasn't been created yet. Thoughts? – Matt Dec 20 '10 at 17:45
  • @mega-matt: Ugh. Good point. Since the session state acquisition occurs later in the pipeline, you're more or less forced into managing this via cookies. Perhaps you drop a "successful login" "session cookie" (no expiration date) post login? The presence of that cookie and the absence of the auth cookie would flag an expiring authentication. If they close the browser and come back, the "successful login" cookie would be gone and you just let forms authentication work as usual. This solution is similar to others here; however, you are able to detect the condition before any redirect. – Brett Dec 20 '10 at 19:03
1

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.

John Christensen
  • 5,020
  • 1
  • 28
  • 26