IIS7 - MultiAuth

What does it accomplish?

MultiAuth is a sample for people who wants to use the same website for internal and external purpose but with either Windows Authentication (internal) or Basic Authentication (external) access.

 

How does it work?

1.       Enable both “Basic Authentication” and “Windows Authentication” for the site (or vdir)

2.       During EndRequest in the pipeline, for the 401 response

a.       Remove all “WWW-Authenticate” headers (context.Response.Headers.Remove(“WWW-Authenticate”))               

b.      check the “host” in http header and

                                                               i.      if host url is internal then add WWW-Authenticate: Negotiate and WWW-Authenticate: NTLM

                                                             ii.      if host url is external then add WWW-Authenticate: Basic realm=”<host>”

 

 

Example URL's

http://computername/multiauth/time.aspx would use “Windows Authentication”

http://computername.domain.com/multiauth/time.aspx would use “Basic Authentication”

 

Main portion of the code to get this functionality shown below

 

public void IssueAuthenticationChallenge(Object source, EventArgs e)
{
    HttpApplication application = (HttpApplication)source;
    HttpContext context = application.Context;

    // Issue authentication challenge according to configuration
    // Authorization header starting with TlRMTVNTUA = NTLMSSP
    if (context.Response.StatusCode == HttpNotAuthorizedStatusCode) 
    {
        authorizationHeader = context.Request.Headers[HttpAuthorizationHeader];
        if (!((authorizationHeader == null) || (authorizationHeader.Equals(String.Empty))))
        {
            if (authorizationHeader.Contains("Negotiate") || authorizationHeader.Contains("NTLM") || authorizationHeader.Contains("Basic"))
            {
                //2nd 401 in case of NTLM
                context.Response.Headers.Add("MultiAuth", "Second round of 401 so ignore"); //adding comments for easy http debug trace
            }
        }
            else
            {
                // remove all WWW-Authenticate headers and add only what is required    
                context.Response.Headers.Remove(HttpWWWAuthenticateHeader);

                hostName = context.Request.Headers["host"];
                if (hostName.Contains(externalName))
                {
                    //adding comments to debug through http trace
                    context.Response.Headers.Add("MultiAuth", "Adding Basic, Status:" + context.Response.StatusCode); 
                    context.Response.AddHeader(HttpWWWAuthenticateHeader, "Basic realm =\"" + externalName + "\"");
                }
                else if (hostName.Contains(internalName))
                {
                    //adding comments to debug through http trace
                    context.Response.Headers.Add("MultiAuth", "Adding Integrated, Status:" + context.Response.StatusCode); 
                    context.Response.AddHeader(HttpWWWAuthenticateHeader, "Negotiate");
                    context.Response.AddHeader(HttpWWWAuthenticateHeader, "NTLM");
                }
            }
    }
}
Yea, its that simple to achieve things using IIS7 new integrated pipeline with a mix of managed code Smile

Author

Sukesh Sukesh Ashok Kumar
Works @ Microsoft
More...

Chat with me!
who's online

Disclaimer

All opinions posted here are those of the author and are in no way intended to represent the opinions of his employer. All posts are provided "AS IS" with no warranties, and confers no rights. © Copyright 2010

Recent Comments

Comment RSS

Sign in