Tuesday, November 24, 2009

Custom 401 for MOSS 2007


  • Handling 401 Error under the WSS 3.0/MOSS 2007 requires special handling.
  • Unlike other Error messages that occur after the user is authenticated, all the browser requests handled through complete  ASP.Net pipe line and further WSS SPRequesthandler/SPPageFactory.
  • In case of FileNotFound there is actually an object model property under the SPApplication object, which is unique and easier to handle.

How MOSS presents 401 Error Message?

  • Under the context of hawkeye portal, were the users are restricted by means of an active directory group, users who are part of the group will get authenticated and are allowed to browse the portal.
  • Users who are part of WSGC domain but are not part of the restricted AD group, will not get authenticated.
  • Upon login attempt with proper username/password entry, user will be redirected http://<PortalURL>/_Layouts/accessdenied.aspx page.
  • Above page is the standard MOSS Access Denied Error Message page.

How does Authentication work in IIS and Browser?

  • When user points the browser to the hawkeye portal, the browser first sends out the request without the user credential.
  • IIS checks to see if the request site is security enabled.
  • If the site is security enabled (in hawkeye case it is Windows Authentication), then IIS challenges the browser to provide the credentials by means of sending a 401 status code back to browser.
  • Browser then looks at 401 and understands that it is now required to provide a credential.
  • Browser then looks up if it has user credentials.
    • If the IE setting is set to Login using current user login then the browser sends the current user name/password.
    • If the IE setting is set to Prompt for login then the users are prompted for login.
    • If the browser does not have a credential then the browser displays the 401 error message by looking up the local 401 error message (This is a page from IE client side)
  • When the browser provide a credential, IIS server takes on checking for the authentication for given user/password.
    • If the user is authenticated, the requested page is served.
    • If the user is a valid Active directory account then the SharePoint redirects the user to http://<PortalURL>/_Layouts/accessdenied.aspx page which is SharePoint error page.
    • If the user is not valid Active directory account then the client side IE 401 error message is displayed.

What 401 error condition can you handle in SharePoint?

  • You can only handle the 401 error condition for a valid AD user accounts but which do not have access to the portal. This is the only condition that Server handles.
  • You can not handle the 401 error condition for non valid AD user accounts.

What are the challenges in SharePoint with handling 401 error?

  • When the 401 error condition occurs for a valid AD user account  with no access to the site, SharePoint page handler will take over the call and manages to redirect to /_Layouts/accessdenied.aspx">/_Layouts/accessdenied.aspx">/_Layouts/accessdenied.aspx">http://<PortalURL>/_Layouts/accessdenied.aspx.
  • Above SharePoint behavior process ignores any web.confg <CustomErrors> settings.
  • The only way to intercept this redirection is by implementing a custom Http handler.
  • Under the http handler, by subscribing to EndRequest event and by trapping for the page redirect where the url is /_layouts/accessdeined.aspx, and then redirecting to your custom error page.
  • You can implement your own custom error page under the sharepoint context  at the given below URL location for example.
  • /_layouts/<YourCompanyName>/MyCustomAccessDeined.aspx


Below is the sample code base for http module. Substitute your <Company Name>. Compile this into a signed assembly.

   1:  using System;

   2:  using System.Collections.Specialized;

   3:  using System.Configuration;

   4:  using System.Web;



   7:  namespace Rajesh.MOSS401Redirector

   8:  {

   9:      public class RedirectorHttpModule : IHttpModule

  10:      {


  12:          public void Init(HttpApplication context)

  13:          {       

  14:              context.EndRequest += new EventHandler(context_EndRequest);                

  15:          }


  17:          protected void context_EndRequest(object sender, EventArgs e)

  18:          {

  19:              if (sender is HttpApplication)

  20:              {

  21:                  HttpApplication application = (HttpApplication)sender;



  24:                  if application.Request.HttpMethod == "GET")

  25:        {

  26:                      HttpContext context = application.Context;

  27:                      if (context.Request.Url.ToString().ToLower().Contains("/_layouts/accessdenied.aspx"))

  28:                      {

  29:                          HttpContext.Current.Server.ClearError();

  30:                          HttpContext.Current.Response.Clear();

  31:                          HttpContext.Current.Response.Redirect("/_layouts/<YourCompanyName>/AccessDenied.aspx", false);

  32:                      }


  34:                   }


  36:           }

  37:    }

Deployment and configuration

  1. Deploy the redirector assembly Rajesh.MOSS401Redirector.dll to the GAC on all FEWs.

  2. Deploy your custom error page under C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\<YourCompanyName>\

  3. Add the following httpModule section to the web application web.config:




      <add name="RedirectorHttpModule" type="Rajesh.MOSS401Redirector.RedirectorHttpModule, Rajesh.MOSS401Redirector, Version=, Culture=neutral, PublicKeyToken=4f1f85ae373342d6" />




     4.Test by login in with user with portal access, and user with no portal access.

     5. This test solution do not have proper implementation of the Custom Error page, it was meant to be a sample test only. You will need to implement proper supported SharePoint page.