Is it possible to use RedirectToAction() inside a custom AuthorizeAttribute class?
Using ASP.Net MVC 2, is there any way to use the RedirectToAction() method of the Controller class inside a class that is based on the AuthorizeAttribute
class?
public class CustomAttribute : AuthorizeAttribute {
protected override bool AuthorizeCore(HttpContextBase context) {
// Custom authentication goes here
return false;
}
public override void OnAuthorization(AuthorizationContext context) {
base.OnAuthorization(context);
// This would be my ideal result
context.Result = RedirectToAction("Action", "Controller");
}
}
I'm looking for a way to re-direct the user to a specific controller / action when they fail the authentication instead of returning them to the login page. Is it possible to have the re-direct URL generated for that controller / action and then use RedirectResult()? I'm trying to avoid the temptation to just hard-code the URL.
You can/should override HandleUnauthorizedRequest
instead of OnAuthorization
. Here's the default implementation:
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
// Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
filterContext.Result = new HttpUnauthorizedResult();
}
You can't use Controller.RedirectToAction
, but you can return a new RedirectToRouteResult
.
So you can do:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
// Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "ActionName" },
{ "controller", "ControllerName" }
});
}
You can do something like this:
var routeValues = new RouteValueDictionary();
routeValues["controller"] = "ControllerName";
routeValues["action"] = "ActionName";
//Other route values if needed.
context.Result = new RedirectToRouteResult(routeValues);
This is the way the framework does it when you call "RedirectToAction()" in your controller.
In case anyone else is interested in this question. This can be solved in a simpler way (at least using MVC 3, don't know about MVC 2):
Just create a small private controller in your custom AuthorizeAttribute:
private class RedirectController : Controller
{
public ActionResult RedirectWhereever()
{
return RedirectToAction("Action", "Controller");
}
}
This can easily be used in your HandleUnauthorizedRequest method (see Craigs answer):
filterContext.Result = (new RedirectController()).RedirectWhereever();