Essentially I want to show a friendly message when someone is not part of a role listed in my attribute. Currently my application just spits the user back to the log in screen. I've read a few posts that talk about creating a custom attribute that just extends [AuthorizeAttribute], but I'm thinking there's got to be something out of the box to do this?
can someone please point me in the right direction of where I need to look to not have it send the user to the log in form, but rather just shoot them a "not authorized" message?
The out-of-the-box behavior is that the [Authorize] attribute returns an HTTP 401. The FormsAuthenticationModule (which is loaded by default) intercepts this 401 and redirects the user to the login page. Take a look at System.Web.Security.FormsAuthenticationModule::OnLeave in Reflector to see what I mean.
If you want the AuthorizeAttribute to do something other than return HTTP 401, you'll have to override the AuthorizeAttribute::HandleUnauthorizedRequest method and perform your custom logic in there. Alternatively, just change this part of ~\Web.config:
And make it point to a different URL, like ~/AccessDenied.
Very similar to crazyarabian, but I only redirect to my string if the user is actually authenticated. This allows the attribute to redirect to the standard logon page if they are not currently logged in, but to another page if they don't have permissions to access the url.
I ran into this issue a few days ago and the solution is a bit detailed but here are the important bits. In
AuthorizeAttribute
theOnAuthorization
method returns aHttpUnauthorizedResult
when authorization fails which makes returning a custom result a bit difficult.What I ended up doing was to create a CustomAuthorizeAttribute class and override the OnAuthorization method to throw an exception instead. I can then catch that exception with a custom error handler and display a customized error page instead of returning a 401 (Unauthorized).
then in your web.config you can set custom handlers for specific errors:
and then implement your own ErrorController to serve up custom pages.
On IIS7 you need to look into setting
Response.TrySkipIisCustomErrors = true;
to enable your custom errors.I might be a little late in adding my $0.02, but when you create your CustomAuthorizationAttribue, you can use the AuthorizationContext.Result property to dictate where the AuthorizeAttribute.HandleUnauthorizedRequest method directs the user.
Here is a very simple example that allows you to specify the URL where a user should be sent after a failed authorization:
And if I wanted to redirect the user to /Error/Unauthorized as suggested in a previous post:
If simplicity or total control of the logic is what you want you can call this in your action method:
It returns a bool and you can do the rest of your logic depending on that result.
Another one that I've used in some cases is:
I think that returns a string[] but don't quote me on that.
EDIT: An example always helps...
As long as your return type is "ActionResult" you could return any of the accepted return types (ViewResult, PartialViewResult, RedirectResult, JsonResult...)