1

I have an ASP.NET MVC4 application. I created a Login page. If a user log in to the system, I register user's information in to session. I added a filter for checking session variable. If user didn't log in to the system, I want to redirect user to my login controller.

public class SecurityAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Session["User"] == null)
            {
                filterContext.HttpContext.Response.RedirectToRoute("Default", new
                {
                    controller = "Login",
                    action = "DoLogin",
                    returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri
                });
            }
            base.OnActionExecuting(filterContext);
        }
    }

I am using this attribute at controller level.

[SecurityAttribute]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Name"] = ((UserEntity)Session["User"]).Name;
            ViewData["Surname"] = ((UserEntity)Session["User"]).Surname;
            return View();
        }
    }

OnActionExecuting method fires before action executing, but redirect occures after action method in my home controller. Because session variable is null, I get an error in index action. How can I fix this?

1 Answer 1

2

You should assign the Result property on the filterContext if you want to short-circuit the execution of the controller action. Just like that:

public class SecurityAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Session["User"] == null)
        {
            var values = new
            {
                controller = "Login",
                action = "DoLogin",
                returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri
            };
            var result = new RedirectToRouteResult("Default", new RouteValueDictionary(values));

            filterContext.Result = result;
        }
    }
}

Also it would have been semantically more correct to write an authorization filter for that purpose and rely on the built-in Forms Authentication rather than reinventing wheels with Session and stuff.

So simply:

[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        string username = User.Identity.Name;
        SomeUserModel user = GetUserFromBackend(username);
        return View(user);
    }
}

You can read more about Forms Authentication at MSDN: http://msdn.microsoft.com/en-us/library/ff647070.aspx

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.