Do ASP.Net MVC Controller Attributes Execute Before or After the Action?
Consider the following code:
[Authenticate(Order = 1)]
public ActionResult SomeActionThatRequiresAuthentication()
{
var model = new SomeViewModel();
// Do something with an authenticated session/user...
return View(model);
}
Does the Authenticate
attribute happen before or after the code inside the SomeActionThatRequiresAuthentication
method is executed?
I am asking this because I have a Attribute that does something like this:
public class Authenticate : CustomAuthorizeAttribute
{
开发者_如何学Python public override void OnAuthorization(AuthorizationContext filterContext)
{
if (!UserService.IsAuthenticated && !HttpContext.Current.Response.IsRequestBeingRedirected)
HttpContext.Current.Response.Redirect(ViewUtil.Actions.User.LogOnUrl());
}
}
As you can see the attribute will redirect a user if the user is not authenticated. However it appears that the redirect only happens after the action executes. This is causing problems because I made the assumption the user is authenticated when executing the action. First I need to understand if the attributes are supposed to happen before or after the action is executed, or am I thinking of the workflow completely wrong?
Thanks, Paul
After researching this some more it is clear that the filterContext.Result
has to be set for this to work. After making a small change in my Authorize attribute, it is now working:
public class Authenticate : CustomAuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (!UserService.IsAuthenticated && !HttpContext.Current.Response.IsRequestBeingRedirected)
filterContext.Result = new RedirectResult(ViewUtil.Actions.User.LogOnUrl());
}
}
You're correct, Attributes execute before the action in question, so [Authenticate]
should most certainly execute first and, if the user is not authenticated, the Action code never executes until after the user is redirected, authenticates and is redirected back to this action.
Edit based on comment: the MVC Framework OnAuthorizatrion
method (source here) doesn't redirect, but sets the filterContext.Result to a `HttpUnauthorizedResult()' (which just sets a 401 status code). That result causes the authentication module to redirect the user to the login page. Assuming that the rest of your custom implementation is standard (not overriden or calling the base methods) changing this
HttpContext.Current.Response.Redirect(ViewUtil.Actions.User.LogOnUrl());
to this (or something similar, as long as you set the Result)
filterContext.Result = new HttpUnauthorizedResult();
should do the trick, at at least get your further down the road.
精彩评论