Tuesday, October 18, 2011

Using multiple authentication modes in a single ASP.NET application


Summary
ASP.NET only allows a single authentication mode to be configured for each application. Some applications may require different modes for different paths. For example, if an application uses Forms authentication for users of the public site, and Windows authentication for users of the administration site.
Resolution
One solution is to create two separate applications; one for the public site using Forms authentication, and one for the administration site using Windows authentication. However, this will mean that resources in the public application cannot be accessed from the administration application using app-relative paths (e.g. /images/logo.jpg).
A better solution is to use the global.asax file to handle theFormsAuthentication_OnAuthenticate event, and apply Windows authentication where appropriate.
  1. In IIS, open the properties of the administration folder;
     
  2. Under "Directory Security", edit the anonymous access and authentication settings, and disable anonymous access;
     
  3. Edit the web.config file, and configure the application to use Forms authentication;
     
  4. Add the following code to the global.asax file in the root of the application:



<%@ Application Language="C#" %>
<%@ Import Namespace="System.Security.Principal" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Web.Security" %>
 
<script runat="server">
 
public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e)
{
    if (null == e) throw new ArgumentNullException("e");
     
    // Check that we have a Windows user
    WindowsIdentity winUser = e.Context.Request.LogonUserIdentity;
    if (null == winUser) return;
     
    // Check that the path allows Windows authentication
    string path = VirtualPathUtility.ToAppRelative(e.Context.Request.Path);
    if (!IsWindowsAuthenticated(path, e.Context)) return;
     
    // Don't allow guest accounts to access
    if (winUser.IsAnonymous || winUser.IsGuest || winUser.IsSystem) return;
     
    WindowsPrincipal winPrincipal = new WindowsPrincipal(winUser);
    if (winPrincipal.IsInRole("Guests")) return;
     
    e.User = winPrincipal;
}
 
private static bool IsWindowsAuthenticated(string path, HttpContext context)
{
    if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
    if (null == context) throw new ArgumentNullException("context");
     
    // Check that the path starts with the restricted folder:
    if (path.StartsWith("/restricted/", StringComparison.OrdinalIgnoreCase)) return true;
     
    return false;
}
 
</script>



      5. Requests to the administration folder will now use Windows authentication; the rest of the site will continue to use Forms authentication

1 comment:

  1. This is not work.

    LogonUserIdentity use current Form authentication. No execute Windows authentication procedure.

    ReplyDelete