![]() |
Web Development »
ASP.NET »
General
Intermediate
Redirecting to custom 401 page when "Access denied" occures within an ASP.NET application with Windows authenticationBy George MamaladzeThis article answers a simple question: What to do when custom error page for error 401 in web.config is not working? How to replace the default ASP.NET "Access denied" page? |
C#, Windows, .NET 1.0, .NET 1.1, .NET 2.0, ASP.NET, IIS, VS.NET2003, VS2005, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
If you have an ASP.NET application with authentication mode set to Windows:
<authentication mode="Windows"/>
<authorization>
<deny users="?" />
</authorization>
Then all Windows users can access your pages but those without Windows login (from internet) will receive an ASP.NET "Access Denied 401" page. I have decided to replace this default message with some custom page. After couple of hours Googling, I found out that this is a very common problem and all the workarounds which seem to be reasonable does not work. Here are some of them:
<customErrors defaultRedirect="ErrorPage.asp­x" mode="On">
<error statusCode="401" redirect="AccessDenied.aspx" />
</customErrors>
This works fine with statusCode="404" but not with 401.
protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
if (!Request.IsAuthenticated) Response.Redirect(
"AccessDenied.aspx");
}
It is also useless, because even the browsers with valid credentials make two posts, one without credentials and having Request.IsAuthenticated=false and the other one with credentials and having Request.IsAuthenticated=true. Browsers without credentials make only one post. It means you are not able to determine if the first post having Request.IsAuthenticated=false comes from an unauthorized browser or not.
Then I found an answer from a Guru at microsoft.public.dotnet.framework.aspnet.security newsgroup.
That's correct. There's no way around that. The way wininet authentication works is that if the resource you are requesting does not allow anonymous access, a 401 is sent back to the browser. If the resource is using Windows Integrated authentication and the browser is configured to automatically send credentials, the token is sent back and the user is authenticated. In the case of Basic authentication, a login prompt is displayed and the user must log in.
If you intercept the 401 and redirect somewhere, you hijack the browser's ability to challenge. There is no way around that.
Jxx Cxxxxxx, MCSE, MCSD [MSFT], Developer Support, ASP.NET.
That was also the result of my research. The whole thing works like this:
The workaround is to manipulate the content of "401 Access Denied" response. The browser uses the header of this response to determine 401 case. It means we can manipulate the HTML content without influencing the whole challenge. For instance we can add the following code in the Application_EndRequest event of Global.asax.cs.
protected void Application_EndRequest(Object sender,
EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context.Response.Status.Substring(0,3).Equals("401"))
{
context.Response.ClearContent();
context.Response.Write("<script language="javascript">" +
"self.location='../login.aspx';</script>");
}
}
Now, the whole thing works like this:
The sample project has only a few relevant lines of code in the Application_EndRequest event of Global.asax.cs. The page default.aspx is accessible only to authorized Windows users. If access is denied the page PublicArea/AccessDenied.aspx will be called. The folder PublicArea is according to local Web.config also accessible for anonymous users.
Attention: The IIS website must be configured to allow anonymous access.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 3 Aug 2005 Editor: Rinish Biju |
Copyright 2005 by George Mamaladze Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |