I have an ASP.NET MVC3 application with Windows Authentication deployed to IIS6. When an authenticated user clicks on a link that they are not authorized to view, they are prompted to enter their username and password (in a browser dialog, not a page), as expected.
However, after clicking Cancel or entering invalid credentials three times, instead of seeing the a 401 Unauthorized page, I see a blank white page.
Looking at Fiddler, there are three requests/responses after clicking Cancel. Here are the response summaries and headers:
ASP.NET Access is denied message (401.2)
HTTP/1.1 401 Unauthorized Date: Fri, 20 Jul 2012 14:34:21 GMT Server: Microsoft-IIS/6.0 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET X-AspNet-Version: 4.0.30319 Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 1701 Proxy-Support: Session-Based-Authentication
IIS You are not authorized to view this page (401.1)
HTTP/1.1 401 Unauthorized Content-Length: 1539 Content-Type: text/html Server: Microsoft-IIS/6.0 WWW-Authenticate: NTLM TlRMTVNTUAACAAAADAAMADgAAAAF... (omitted for brevity) X-Powered-By: ASP.NET Date: Fri, 20 Jul 2012 14:34:21 GMT Proxy-Support: Session-Based-Authentication
Empty response
HTTP/1.1 401 Unauthorized Date: Fri, 20 Jul 2012 14:34:21 GMT Server: Microsoft-IIS/6.0 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET X-AspNet-Version: 4.0.30319 X-AspNetMvc-Version: 3.0 Cache-Control: private Content-Length: 0 Proxy-Support: Session-Based-Authentication
How do I get this to display a 401 error page?
Update 1:
Here is my web.config errors section.
<customErrors mode="RemoteOnly" defaultRedirect="~/Error" />
I'm also using HandleErrorAttribute
.
I suspect that IIS is returning the blank page rather than ASP.NET, but I'm not sure how to prove that.
Update 2:
This is interesting. If I refresh the blank page, I see the ASP.NET Access is Denied message.
I came up with this work around after looking into 401 redirection as @AndrewHagner suggested. It's based on this answer. I implemented AuthorizeAttribute
and overrode HandleUnauthorizedRequest()
.
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
var authenticatedUnauthorizedRouteValues =
new RouteValueDictionary(new {controller = "Error", action = "Index"});
filterContext.Result = new RedirectToRouteResult(authenticatedUnauthorizedRouteValues);
filterContext.Controller.TempData["message"] =
"You are not authorized to view this page.";
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
So as I understand, this will catch unauthorized requests in the MVC pipeline before being sent to IIS. This gives me the opportunity to redirect to a user friendly not authorized page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With