Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Authorize Attribute + HttpUnauthorizedResult + FormsAuthentication

After browsing the MVC section on CodePlex I noticed that the [Authorize] attribute in MVC returns a HttpUnauthorizedResult() when authorization fails (codeplex AuthorizeAttribute class).

In the source of HttpUnauthorizedResult() from CodePlex is the code (I'm not allowed to enter another URL as my rep isn't high enough, but replace the numbers on the URL above with 22929#266476):

// 401 is the HTTP status code for unauthorized access - setting this
// will cause the active authentication module to execute its default
// unauthorized handler
context.HttpContext.Response.StatusCode = 401;

In particular, the comment describes the authentication module's default unauthorized handler.

I can't seem to find any information on this default unauthorized handler. In particular, I'm not using FormsAuthentication and when authorization fails I get an ugly IIS 401 error page.

Does anyone know about this default unauthorized handler, and in particular how FormsAuthentication hooks itself in to override it?

I'm writing a really simple app for my football team who confirm or deny whether they can play a particular match. If I enable FormsAuthentication in the web.config the redirect works, but I'm not using FormsAuthentication and I'd like to know if there's a workaround.

like image 205
Anthony Avatar asked Jan 26 '10 16:01

Anthony


1 Answers

If you have Reflector, take a look at System.Web.Security.FormsAuthenticationModule.Init(). This method hooks Application_EndRequest and calls OnLeave(). The OnLeave() method checks that the response code is HTTP 401. If it is, then the module performs a redirect rather than bubbling the 401 up to the client. (This logic is what the comment is referring to as the 'default unauthorized handler.') In your particular case, ASP.NET is letting the 401 bubble up to the client, but IIS is intercepting it and displaying an ugly error page.

You can do something very similar from within Global.asax. Make a method Application_EndRequest; this method will be called at the end of every request serviced by your application. From here, you can do whatever you want. If you want to check if the response is a 401 and redirect them to a different page, you can do so from here.

like image 106
Levi Avatar answered Sep 21 '22 22:09

Levi