Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With ASP.NET MVC redirect to login page when session expires

I am using ASP.NET MVC. I want to redirect to login page when session expires. How can I achieve this? If I am doing an AJAX call to a method in controller then if my session expires in that situation also I want to redirect to login page.

like image 489
Manjusha Kondapally Avatar asked Aug 17 '11 10:08

Manjusha Kondapally


4 Answers

you could do this by 3 ways:

  1. Create a filter to your actions and apply it programming a code in OnActionExecuting (before the action been executed), http://www.asp.net/mvc/tutorials/understanding-action-filters-cs

  2. Create a base class (inheriting from Controller class) and make your controllers inherits from this one. In this class you could overwrite a method called OnActionExecuting, like the filter.

  3. Don't use Session for Authentication, you can use Forms authentication and keep it simple to use, look this: http://weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework-using-forms-authentication.aspx

In my opinion, the solution 3 is better than other. I hope it works for you!

like image 97
Felipe Oriani Avatar answered Oct 09 '22 22:10

Felipe Oriani


because it's possible to copy the security-cookie of the Forms-Authentication use it to simulate a registered user I use the following attribute to bind the authentication to the current session lifetime.

To make the Attribute work you have to set session["user"] = MyUser on login and call session.abandom() on logout. I don't know if the redirect works with ajax calls - that's something you have to try.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class CheckUserSessionAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpSessionStateBase session = filterContext.HttpContext.Session;
        var user = session["User"];

        if (((user == null) && (!session.IsNewSession)) || (session.IsNewSession))
        {
            //send them off to the login page
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content("~/Account/LogOff");
            session.RemoveAll();
            session.Clear();
            session.Abandon();
            filterContext.HttpContext.Response.Redirect(loginUrl, true);
        }
    }
}
like image 29
Michael Avatar answered Oct 09 '22 22:10

Michael


This answers is heavily based on Michaels except it works ;-)

I changed it to take a delegate for checking if the session has ended so it can work in different apps which might have different ways of determining this and also the login page might be different in other apps. In the Global.asax.cs Application_Start() the code I have in my app is

CheckUserSessionAttribute.CheckSessionAlive = session => (session.GetUser() != null);
CheckUserSessionAttribute.LoginUrl = "~/Account/Login";

Then the attribute class is as follows

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class CheckUserSessionAttribute : ActionFilterAttribute
    {
        public static String LoginUrl { get; set; }
        public delegate bool CheckSessionDelegate(HttpSessionStateBase session);

        public static CheckSessionDelegate CheckSessionAlive;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            HttpSessionStateBase session = filterContext.HttpContext.Session;
            if ((CheckSessionAlive == null) || (CheckSessionAlive(session)))
                    return;


            //send them off to the login page
            var url = new UrlHelper(filterContext.RequestContext);
            var loginUrl = url.Content(LoginUrl);
            session.RemoveAll();
            session.Clear();
            session.Abandon();

            filterContext.HttpContext.Response.StatusCode = 403;
            filterContext.HttpContext.Response.Redirect(loginUrl, false);
            filterContext.Result = new EmptyResult();

        }
    }

From your controller just add the [CheckUserSession] attribute above the class or the individual actions.

like image 35
Alan Macdonald Avatar answered Oct 09 '22 22:10

Alan Macdonald


Another plausible solution could be found in here:

Overriding Controller Methods for session Timeout handling

like image 44
T Gupta Avatar answered Oct 09 '22 20:10

T Gupta