Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying action filter globally giving Redirect Loop exception in MVC

Problem Statement:

I'm trying to redirect user to login page if session expires or if user tries to access any view without logging in MVC 4 using razor.

  • Instead of applying action filter globally in filter.config if i use filter attribute for every action methods it works fine.
  • I don't want apply this action filter to each and every action method.

I want to apply it globally.How to avoid redirect loop by applying action filter globally?? How to achieve this??

Login Controller :

//Get Method
public ActionResult Index(string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    return View();
}

//Post Method
[HttpPost]
public ActionResult Index(LoginModel loginModel, string returnUrl)
{
    if (ModelState.IsValid)
    {
        objLoginDC.LoginID = loginModel.LoginID;
        objLoginDC.Password = loginModel.Password;
        if (objSvcMasterConfig.IsValid(objLoginDC))
        {
            var varLoginTenantUserDetails = objSvcMasterConfig.GetLoginUserDetails(objLoginDC);
            Session["User"] = varLoginUserDetails[0];
            FormsAuthentication.SetAuthCookie(objLoginDC.LoginID, objLoginDC.RememberMe);

            return RedirectToLogin(returnUrl);
        }
        else
        {
            ModelState.AddModelError("", "The Log In ID or Password provided is incorrect.");
        }
    }

    return View(loginModel);
}

Filters(Action Filter):

[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))
        {
            session.RemoveAll();
            session.Clear();
            session.Abandon();

            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Login" }, { "action", "Index" } });
        }
        base.OnActionExecuting(filterContext);
    }
}

Filter Config.cs:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new Filters.CheckUserSessionAttribute());
    }
}
like image 474
Vishal I P Avatar asked Oct 21 '22 10:10

Vishal I P


1 Answers

You could try not executing your filter logic when the controller is Login and the action is Index:

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

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //do not execute the filter logic for Login/Index
        if (filterContext.RouteData.GetRequiredString("controller").Equals("LogIn", StringComparison.CurrentCultureIgnoreCase)
            && filterContext.RouteData.GetRequiredString("action").Equals("Index", StringComparison.CurrentCultureIgnoreCase)){
            return;
        }

        HttpSessionStateBase session = filterContext.HttpContext.Session;
        var user = session["User"];

        if (((user == null) && (!session.IsNewSession)) || (session.IsNewSession))
        {
            session.RemoveAll();
            session.Clear();
            session.Abandon();

            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Login" }, { "action", "Index" } });
        }
        base.OnActionExecuting(filterContext);
    }
}
like image 131
Daniel J.G. Avatar answered Oct 23 '22 11:10

Daniel J.G.