26

I have an ASP.NET MVC4 application where I am implementing sessionTimeout like:

<configuration>
  <system.web>
    <sessionState timeout="2"></sessionState>
  </system.web>
</configuration>

And in authentication:

<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="1" />
    </authentication>
  </system.web>
</configuration>

After the session has expired (2 mins), I need to redirect to the logon page, but the redirection doesn't occur.

How can I change the code so that it will redirect?

KyleMit
  • 45,382
  • 53
  • 367
  • 544
Jonathan
  • 1,549
  • 7
  • 31
  • 51
  • 1
    Please check the below link. It may help you. [Login page url][1] [1]: http://stackoverflow.com/questions/356982/how-to-redirect-to-a-dynamic-login-url-in-asp-net-mvc – RGR Dec 14 '12 at 05:55

3 Answers3

32

One way is that In case of Session Expire, in every action you have to check its session and if it is null then redirect to Login page.

But this is very hectic method To over come this you need to create your own ActionFilterAttribute which will do this, you just need to add this attribute in every action method.

Here is the Class which overrides ActionFilterAttribute.

public class SessionExpireFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext ctx = HttpContext.Current;

            // check if session is supported
            CurrentCustomer objCurrentCustomer = new CurrentCustomer();
            objCurrentCustomer = ((CurrentCustomer)SessionStore.GetSessionValue(SessionStore.Customer));
            if (objCurrentCustomer == null)
            {
                // check if a new session id was generated
                filterContext.Result = new RedirectResult("~/Users/Login");
                return;
            }

            base.OnActionExecuting(filterContext);
        }
    }

Then in action just add this attribute like so:

[SessionExpire]
public ActionResult Index()
{
     return Index();
}

This will do you work.

Victorio Berra
  • 2,077
  • 2
  • 20
  • 37
user1006544
  • 1,384
  • 2
  • 15
  • 26
  • Basically i need to create the class you defined in each of my controller and each action method i need to give **ActionFilterAttribute** and for index method i need to give **[SessionExpire]**. Is that so – Jonathan Dec 14 '12 at 07:09
  • 1
    no you just need to create that class in your app_start only one and add that attribute to the action – user1006544 Dec 14 '12 at 07:11
  • U mean in the global.asax.cs page i need to add this code in the Application_Start() function – Jonathan Dec 14 '12 at 07:18
  • ya OnActionExecuting add this method – user1006544 Dec 14 '12 at 08:33
  • No not yet. what is CurrentCustomer there what namespace should i include for that. And can i get a pop up window intimating the user that the session is timed out – Jonathan Dec 14 '12 at 09:28
  • yar current cust is my session object , here add your session object. namespace is already written in global.asax so no need . pop thing is you have to add this , i have just given the logic for session expire check – user1006544 Dec 14 '12 at 09:34
  • Add one App_Start Folder either , then add one class file,then add namespace - 'yourprojectName.App_Start' then in that copy paste my code and use that attribute – user1006544 Dec 14 '12 at 09:43
  • I also have a problem with the Customer part, i have make a class in the App_Start And included the correct namespace, but it wont regognize customer? Any idea? – Tim Mar 13 '13 at 07:30
  • somebody could you explain me What is the class CurrentCustomer and SessionStore I have error in this. – raranibar Mar 31 '14 at 14:14
  • As user1006544 has stated, you have to implement CurrentCustomer and SessionStore by yourself. http://stackoverflow.com/questions/2417197/asp-net-mvc-session-usage ? – Jana Weschenfelder Jul 21 '15 at 11:14
  • Excellent Solution Buddy. 1000+ for you. – Chandan Kumar Oct 15 '16 at 04:30
  • Where i need to set "objCurrentCustomer" to Null? – Parth Akbari May 23 '17 at 12:03
  • can someone tell me why it is not redirecting to the specified url ..could the url be wrong? its not crashing any more but stays on the same page – Samra Aug 30 '17 at 23:43
  • The code is not clear. I can't understand what CurrentCustomer nor SessionStore are. – Dr. MAF May 14 '18 at 10:01
  • The code is checking if the session is active by trying to place an object into that session. That object, is CurrentCustomer. Thus, if the session active, the object can be inserted, and the code passes. Using SessionExpireFilterAttribute is a great idea. but I disagree with the need for the CurrentCustomer object. – 1c1cle Feb 21 '20 at 00:32
28

I discover very simple way to redirect Login Page When session end in MVC. I have already tested it and this works without problems.

In short, I catch session end in _Layout 1 minute before and make redirection.

I try to explain everything step by step.

If we want to session end 30 minute after and redirect to loginPage see this steps:

  1. Change the web config like this (set 31 minute):

     <system.web>
        <sessionState timeout="31"></sessionState>
     </system.web>
    
  2. Add this JavaScript in _Layout (when session end 1 minute before this code makes redirect, it makes count time after user last action, not first visit on site)

    <script>
        //session end 
        var sessionTimeoutWarning = @Session.Timeout- 1;
    
        var sTimeout = parseInt(sessionTimeoutWarning) * 60 * 1000;
        setTimeout('SessionEnd()', sTimeout);
    
        function SessionEnd() {
            window.location = "/Account/LogOff";
        }
    </script>
    
  3. Here is my LogOff Action, which makes only LogOff and redirect LoginIn Page

    public ActionResult LogOff()
    {
        Session["User"] = null; //it's my session variable
        Session.Clear();
        Session.Abandon();
        FormsAuthentication.SignOut(); //you write this when you use FormsAuthentication
        return RedirectToAction("Login", "Account");
    } 
    

I hope this is a very useful code for you.

KyleMit
  • 45,382
  • 53
  • 367
  • 544
Avtandil Kavrelishvili
  • 1,293
  • 2
  • 20
  • 33
  • Probably want to [reset the `setTimeout`](https://stackoverflow.com/questions/1472705/resetting-a-settimeout) on any AJAX calls as the user could continue to interact with the form and keep the session alive on the back end – KyleMit Jan 10 '18 at 21:09
  • 2
    This will redirect to login even if user is still working – BYISHIMO Audace Mar 23 '18 at 16:01
6

There is a generic solution:

Lets say you have a controller named Admin where you put content for authorized users.

Then, you can override the Initialize or OnAuthorization methods of Admin controller and write redirect to login page logic on session timeout in these methods as described:

protected override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
    {
        //lets say you set session value to a positive integer
        AdminLoginType = Convert.ToInt32(filterContext.HttpContext.Session["AdminLoginType"]);
        if (AdminLoginType == 0)
        {
            filterContext.HttpContext.Response.Redirect("~/login");
        }

        base.OnAuthorization(filterContext);
    }
T Gupta
  • 957
  • 11
  • 11