Click here to Skip to main content
15,891,136 members
Articles / All Topics

Custom Error Page 401 Access Denied when Using Windows Authentication

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
6 Oct 2014CPOL4 min read 15.3K   1  
Custom Error Page 401 Access Denied when Using Windows Authentication

ASP.NET provides us with the ability to add custom pages for HTTP errors via Web.config CustomErrors tag. This however does not work when we try to handle the 401 error under Windows authentication. The reason for this is that this error (401) is raised during the Authorization request event on the HttpApplication process pipeline (see below), and Custom error settings are processed during the Action Method invocation (ASP.NET Handler.ProcessRequest event).

HTTP Process Pipeline HTTP 401 Error browser Interaction
Http Process Pipeline

The common interaction between the browser and the server is as follows:

The browser sends request with no authentication tokens.

The server responds with a 401.2 HTTP error.

The browser sends authentication tokens if the user is already logged. If the user is not, the browser shows a login dialog.

Even if the user is logged on, but he does not have the required role for this access, the server returns a 401.2 error and displays the Access Denied Page.

To provide a custom page for the Access Denied error, we should implement the following:

  • Use httpErrors Configuration settings
  • Allow Anonymous Access to content
  • Allow Anonymous Access to controller actions

Use httpErrors Configuration Settings

XML
<configuration>
<system.webServer>
  <httpErrors errorMode="Custom" xdt:Transform="Insert">
    <remove statusCode="401" />
    <error statusCode="401" 
    path="/Error/NotAuthorized" responseMode="ExecuteURL" />
  </httpErrors>
</system.webServer>
</configuration>

*Note that this setting only works when the application is running under IIS. This setting can be added to the Web.Release.config file, so when the deployment is done, these settings are merged into the Web.config file. This is done with the help of the xdt:Transform=insert attribute.

With this setting, we are basically telling IIS that we want to use our own custom page when the 401 error is raised. Note that since the machine.config already has this setting defined, we need to first remove the entry. We can then add the entry with our own directives. In this case, we are doing a server execute in the response mode which requires a relative path to our page or route. There is also support to redirect to an absolute Url. For this case, we are using a controller action named Error.NotAuthorized that is relative to the application.

Allow Anonymous Access to Content

Since our custom error page may need to download images and other resources, we need to add some settings in our web.config to indicate that these resources should be unprotected. This is important because even if we redirect to a custom view, the images and bundled resources would also raise a 401 error, and the page may not look as the rest of the application. To allow access to other content, we can add the following settings to our web.config file.

Location Setting Paths that should be allowed
XML
<location path="Error">
			    <system.web>
			      <authorization>
			        <allow users ="*" />
			      </authorization>
			    </system.web>
			  </location>

Images

 

Error

The route for our custom error page

Bundles

This is the path use to download bundled resources.

Content

For CSS files

Favicon.ico

Favorite icon

*Note add one location setting per path

*Use fiddler to get an idea of the resources that are downloaded

This setting allows all users to have access to the path defined by the location path attribute. We should note that if we are using a particular folder or route for our custom view, this also should be allowed to all users.

Allow Anonymous Access to Controller Action

When using a controller to provide the custom error page, we must allow anonymous access to the action that should process this error. This can be done as follows:

C#
[Authorize]
public class ErrorController : Controller
{
//
// GET: /Error/
public ActionResult Index()
{
return View("Error");
}

//GET: /Error/NotAuthorized
[AllowAnonymous]
public ActionResult NotAuthorized()
{
return View("NotAuthorized", "NoChromeLayout");
}
}

The AllowAnonymous attribute allows non-authenticated users to have access to this request. Our view and layout provide only content which does not required authentication.

How About Using Application EndRequest Handler?

Another approach often used is to implement a redirect on the end request handler (global.asx.cs) as follows:

C#
 protected void Application_EndRequest()
{
// If the user is not authorized redirect to error page
if (Response.StatusCode == 401)
{
Response.ClearContent();
              Response.RedirectToRoute("NotAuthorized ");
}
}

The problem I find with this approach is that it can lead to endless redirect scenario. The end request event is raised multiple times during the request life cycle of a page. The page can download more content like images, CSS, JavaScript files each one sending a request thus raising an EndRequest event. If one of those resources is not properly configured, the status code would also be 401 and another redirect would be initiated.

Conclusion

The HttpError custom page configuration should be less intrusive approach to add custom error pages to our application as it is a configuration task instead of an implementation concern.

This article was originally posted at http://ozkary.blogspot.com/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect OG-BITechnologies
United States United States
Software engineer, author & speaker who enjoys mentoring, learning, speaking and sharing with others about software development technologies. Microsoft MVP.

My Blog

Comments and Discussions

 
-- There are no messages in this forum --