Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Session Start and Action Filter for Session Timeout handling

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;
}
like image 863
LCJ Avatar asked Oct 12 '13 08:10

LCJ


People also ask

How do I set session timeout on my property?

The Timeout property can be set in the Web. config file for an application using the timeout attribute of the sessionState configuration element, or you can set the Timeout property value directly using application code. The Timeout property cannot be set to a value greater than 525,600 minutes (1 year).

What is the default timeout value for session?

Session timeout determines how long the server maintains a session if a user does not explicitly invalidate the session. The default value is 30 minutes.

What is session timeout?

Session timeout represents the event occuring when a user does not perform any action on a web site during an interval (defined by a web server). The event, on the server side, changes the status of the user session to 'invalid' (ie.


1 Answers

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.

like image 55
markegli Avatar answered Sep 28 '22 08:09

markegli