9

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?

3
  • 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? Commented Dec 9, 2010 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. Commented Dec 9, 2010 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. - stackoverflow.com/questions/1352501/… Commented Aug 29, 2011 at 14:39

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

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!

4 Comments

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

1 Comment

I've used this approach in the past as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.