Customizing authorization in ASP.NET MVC
My Controller class is decorated with an AuthorizeAttribute to protect the actions:
[Authorize(Roles = "User Level 2")]
public class BuyController : Controller
{
...
}
Anytime an action is invoked, but the user is not in at least the role "User Level 2", the user is automatically redirected to the login page with a URL like this:
http://localhost:1436/Account/Login?ReturnUrl=%2fBuy
If the user is already logged in, but doesn't have the right security level, this is not an optimal behavior! It would make more sense to display a page which informs the user about the missing level instead of showing the login page.
What can I do to customize this behavior?
Is it possible to pass the required user level to the Login action somehow?
Solution 1:
You can build your own authorize attribute like this:
public class ClubAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Cancel && filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {
{ "clubShortName", filterContext.RouteData.Values[ "clubShortName" ] },
{ "controller", "Account" },
{ "action", "Login" },
{ "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
});
}
}
}
I used this to redirect to a specific club in a club membership site I am building. You could adapt this to your need. BTW, in my case I do redirect to the login page, but I check to see if the user is authorized and if so, display a message that they don't have the correct permissions. No doubt you could also add something to ViewData or TempData to display on the page, but I haven't tried that
EDIT AuthorizationContext.Cancel doesn't exist anymore in RC. "filterContext.Result is HttpUnauthorizedResult" seems to be enough : What happened to filterContext.Cancel (ASP.NET MVC)
Solution 2:
Time has long passed since the last answer.
Since 2009, a lot of progress has been made in the authorization space. In particular, OASIS (the ones behind SAML) have standardized XACML, the eXtensible Access Control Markup Language.
XACML gives developers:
- a usage pattern
- an architecture
- a flexible authorization policy language
XACML is in line with attribute-based access control which NIST recommends be adopted in applications nowadays.
Have a look at this answer for more details.