I am using the Authorize attribute like this:
[Authorize (Roles="Admin, User")]
Public ActionResult Index(int id)
{
// blah
}
When a user is not in the specified roles, I get an error page (resource not found). So I put the HandleError attribute in also.
[Authorize (Roles="Admin, User"), HandleError]
Public ActionResult Index(int id)
{
// blah
}
Now it goes to the Login page, if the user is not in the specified roles.
How do I get it to go to an Unauthorized page instead of the login page, when a user does not meet one of the required roles? And if a different error occurs, how do I distinguish that error from an Unauthorized error and handle it differently?
Add something like this to your web.config:
You should obviously create the
/PageNotFoundand/Unauthorizedroutes, actions and views.EDIT: I’m sorry, I apparently didn’t understand the problem thoroughly.
The problem is that when the
AuthorizeAttributefilter is executed, it decides that the user does not fit the requirements (he/she may be logged in, but is not in a correct role). It therefore sets the response status code to 401. This is intercepted by theFormsAuthenticationmodule which will then perform the redirect.I see two alternatives:
Disable the defaultRedirect.
Create your own
IAuthorizationFilter. Derive fromAuthorizeAttributeand override HandleUnauthorizedRequest. In this method, if the user is authenticated do a redirect to /UnauthorizedI don’t like either: the defaultRedirect functionality is nice and not something you want to implement yourself. The second approach results in the user being served a visually correct “You are not authorized”-page, but the HTTP status codes will not be the desired 401.
I don’t know enough about HttpModules to say whether this can be circumvented with a a tolerable hack.
EDIT 2:
How about implementing your own IAuthorizationFilter in the following way: download the MVC2 code from CodePlex and “borrow” the code for AuthorizeAttribute. Change the OnAuthorization method to look like
where
unauthorizedUrlis either a property on the filter or read from Web.config.You could also inherit from AuthorizeAttribute and override
OnAuthorization, but you would end up writing a couple of private methods which are already in AuthorizeAttribute.