7

I have a MVC4 application with Windows Authentication. User can type url of any of the 10 views to load the application. There is no specific home page

I need to redirect to a session timeout view if the user was idle for more than a minute. I have kept the session timeout value in config file as one minute. And I have created an action filter to check one particular session value. This particular session value is set in the Session_Start of the Global.asax.

But, when the timeout period is over, the request again hits the Session_Start and it is assigning the value. Hence my action filter is not redirecting to the error view. What are the possible solutions to overcome this?

Web.Config

<system.web>
    <!--Impersonate-->
    <identity impersonate="true"/>
        <!--Session Mode and Timeout-->
    <sessionState mode="InProc" timeout="1" />
    <authentication mode="Windows">
    </authentication>
    <authorization>
      <allow users="?" />
    </authorization>    
</system.web>

Action Filter

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class SessionCheckAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
    {
        string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        var activeSession = session["IsActiveSession"];
        if (activeSession == null)
        {
            //Redirect
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content("~/Error/SessionTimeout");
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }
    }
}

Global.ASAX

protected void Session_Start(object sender, EventArgs e)
{
    Session["IsActiveSession"] = DateTime.Now;
}
Raidri
  • 17,258
  • 9
  • 62
  • 65
LCJ
  • 22,196
  • 67
  • 260
  • 418
  • Reference: http://stackoverflow.com/questions/199099/how-to-manage-a-redirect-request-after-a-jquery-ajax-call – LCJ Oct 12 '13 at 12:07
  • And http://stackoverflow.com/questions/16259230/globally-filter-ajax-success-handlers and [408 Error Code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) – LCJ Oct 12 '13 at 12:12

1 Answers1

11

Instead of setting a session value and checking it in your action filter, simply check HttpContext.Current.Session.IsNewSession to see if a new session was created for the current request. Modifying your action filter, you would end up with something like this:

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class SessionCheckAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
    {
        string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        if (session.IsNewSession)
        {
            //Redirect
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content("~/Error/SessionTimeout");
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }

    }
}

if you want to get fancy and make sure they had a previous session before the new session that was created for this request, you can update the if statement to check if an old session cookie was sent with the request:

string cookieHeader = filterContext.HttpContext.Request.Headers["Cookie"];
if (session.IsNewSession && cookieHeader != null && cookieHeader.IndexOf("ASP.NET_SessionId") >= 0)
{
    ...
}

But since it looks like you are sending them to a login page, this is probably not something you have to worry about here. If you do use this check, note that this code assumes the default "ASP.NET_SessionId" cookie name; this could be changed in your web.config, in which case you would need to either update the IndexOf parameter with the new cookie name or get the cookie name programmatically.

Community
  • 1
  • 1
markegli
  • 398
  • 2
  • 11