Frage

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?

War es hilfreich?

Lösung

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top