Question

I'm using the following code to detect session expiry:

public class SessionActionFilterAttribute : ActionFilterAttribute
{
    /// <summary>Called by the ASP.NET MVC framework before the action method executes.</summary>
    /// <param name="filterContext">The filter context.</param>
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // The following code is used for checking if a session has timed out. The default timeout value for ASP.NET is 20mins.
        // The timeout value can be overriden in the Web.config file using the sessionState tag's timeout attribute.
        // <sessionState timeout="5"></sessionState>
        // Check for an existing session.
        if (null != filterContext.HttpContext.Session)
        {
            // Check if we have a new session.
            // IsNewSession cannot discern between: is it a new visitor with fresh session, or an existing visitor with expired session.
            if (filterContext.HttpContext.Session.IsNewSession)
            {
                string cookieHeaders = filterContext.HttpContext.Request.Headers["Cookie"];

                // Check if session has timed out.
                // Does session cookie exist, if so ASP.NET session is expired
                if ((null != cookieHeaders) && (cookieHeaders.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    if (filterContext.HttpContext.Request.IsAuthenticated)
                    {
                        FormsAuthentication.SignOut();
                    }

                    // Redirect to login.
                    filterContext.Result = new RedirectToRouteResult(
                                                                    new RouteValueDictionary 
                                                                    { 
                                                                        { "controller", "Account" }, 
                                                                        { "action", "Index" },
                                                                        { "timeout", "True"}
                                                                    });
                    return;
                }
            }
        }

        // Else continue with action as usual.
        // Session is not expired and function will return false, could be new session, or existing active session
        base.OnActionExecuting(filterContext);
    }
}

Which works fine up to a point...

When the user is logged in and closes the browser before the session times out (without logging out)...

and then attempts to view the site again and to log back in after the session has timed out it is continually redirecting to the login page, i.e. the above code thinks that the session has expired continuously, but I'm guessing that for some reason the cookie remains as 'expired'.

Is there something I'm missing here?

P.S. I'm using the following in the web.config

<sessionState timeout="1"></sessionState>
Was it helpful?

Solution

Gah.... I added the following just before the redirect and it seems to have fixed the issue.... just a bit more testing to be sure:

if (filterContext.HttpContext.Request.Cookies["ASP.NET_SessionId"] != null)
{
    filterContext.HttpContext.Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddDays(-1);
}

filterContext.HttpContext.Session.Abandon();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top