Credentials Screening: Windows Authentication without a Login Dialog Box

It is easy to turn on Windows (also known as NT) authentication on IIS:

  • Check “Integrated Windows authentication”
  • Uncheck the “enable anonymous access” box
  • Set permissions on the file or folder that you want to be the object of authentication.

Once the authentication is turned on, anytime anonymous users access that file (or folder), they will see a login dialog box pop up, asking the users to enter their credentials before letting them to view the file. A slightly different situation will happen to those users whose browser is configured to recognize the site as part of an Intranet domain — the browser will attempt to authentication automatically, and if the authentication is successful, they will be let in without any dialog boxes popping up.

Wouldn’t it be nice if your site would not display a dialog box in either case?

  • If the user can be authenticated automatically, let them in authenticated
  • Otherwise, let the user in as anonymous.

This type of authentication is often needed in Intranet Web sites, where the site provides degrees of customization based on the type of the user, screening every user for authentication, but never explicitly asking for credentials. Hence the term “credentials screening”: have valid credentials? Great! Don’t have any? That’s ok, too.

The biggest challenge in this scenario is the fact that most of the “behind the scenes” work of automatic (integrated) authentication happens outside the boundaries of your client or server applications, handled completely by the browser. In other words, there is no way to control how the process happens using either server-side or client-side code.

What we need here is a function of some sort (let’s call it the screening function) that would allow us to test whether the user can be authenticated and return “true” or “false”. Also, this function will need to be called before the authentication is first attempted. These two assumptions help us outline the following principles:

  • First page that the user hits must have anonymous authentication enabled
  • The screening function must be contained in that first page
  • In order to return a result, the screening function must somehow attempt authentication
  • Authentication attempt is triggered by accessing a page which requires authentication
  • Accessing a page from a client-side function can be performed using variety of methods. One of them is instantiating and using Msxml2.DOMDocument object (there are similar methods for browsers other than Internet Explorer).

After looking at the list above, the implementation of the screening function becomes crystal clear:

function CanAuthenticate()
{
    try
    {
        var dom = new ActiveXObject("Msxml2.DOMDocument");
        dom.async=false;
        dom.load("RequiresAuthentication.xml");
    }
    catch(e)
    {
        return false;
    }
    return true;
}

As you can see, this function attempts to open a document, named “RequiresAuthentication.xml”. If this document has anonymous authentication disabled, the browser will automatically attempt authenticating using existing user credentials. No dialog box will be shown – if authentication fails, an exception will be thrown and the function will return “false”. Otherwise, the document will be opened successfully and the function will return “true”.

The only other issue is to make sure that this function is always called at the beginning of the user session. In ASP.NET, you can accomplish this by subscribing to an event, fired by the built-in session state management module, System.Web.SessionState.SessionStateModule. The name of the event is “Start” and the easiest way to do this is to:

  • Open your application’s Global.asax.cs file
  • Add your code to the body of a pre-built “Session_Start” method.

Because this method is called only once for each user session, you can write it to simply emit the HTML which contains the screening function and then end the response, in order to prevent the actual page from being displayed. Of course, your client-side code must initiate a page reload right after calling the screening function.

Another way of doing it is to develop an HTTP module, which will do the same thing and leave the Global.asax.cs file in its pristine condition. Here you can download a sample implementation of such a module.

A couple of installation instructions:

  • Make “CredentialsScreening” folder a Web application
  • Disable anonymous access to “RequiresAuthentication.xml” file and set its permissions according to your authentication needs.
  • To test, access “Test.aspx” file with your browser.

Well, there you have it – a credentials screening solution. Hope you find it useful. If you do – drop me a note.

UPDATED 10/04/04: Referenced code was updated. For more details, look here.

11 thoughts on “Credentials Screening: Windows Authentication without a Login Dialog Box”

  1. I try to download the example CredentialsScreening.zip, but showit this error:
    Not Found
    Sorry, but you are looking for something that isn’t here.

    I would like to see it to learn more.

    WMA.

  2. Wow! it’s exactly what I was looking for.
    I’m involve in a project which require “mix mode authentication” and I did struggle a lot the find a solution the the NTLM pop up dialog.

    Do you know if a solution exits also for Firefox/ other browsers?

    Thanks,
    Nir

  3. Thank you so much. This is probably the cleanest solution to this problem I have seen yet. This should hold us over till we can get IIS 7 available.

  4. I try to download the example CredentialsScreening.zip, but the link is broken.

    Kind Regards

    Giorgio

  5. Unfortunately, the main promise of this article doesn’t work: a browser still displays that automatic pop-up asking for Windows credentials, in case user is not authenticated [yet]. That remote trick with ActiveXObject(“Msxml2.DOMDocument”) (and I tried XmlHttpRequest too – obviously, no difference) does not allow a browser to silently fail…

    I’m currently using IIS7, but may be able to try it with IIS5.1. I doubt it matters, though.

    Did you actually has it working?

  6. Unfortunately, the main promise of this article doesn’t work: a browser still displays that automatic pop-up asking for Windows credentials, in case user is not authenticated [yet]. Your trick with ActiveXObject(“Msxml2.DOMDocument”) (and I tried XmlHttpRequest too – obviously, no difference) does not allow a browser to silently fail. Obviously, a negotiation between browser and IIS server still happens and causes that automatic pop-up…

    I’m currently using IIS7, but may be able to try it with IIS5.1. I doubt it matters, though.

    Did you actually have it working in the past?

  7. Guys, this article was written in 2004. This was the time when IE6 was the latest browser available from Microsoft and Facebook was just a twinkle in Zuckerberg’s eye. Lots of things have changed since then.

    Please stop trying to make this old solution work 🙂

    1. Unfortunately, this page is the first response from Google for ‘xmlhttprequest firefox “windows credentials”‘ 🙂

  8. Thank you Dimitri! Still, it was a nice way to check windows credentials without displaying automatic pop-up…
    We implemented a dual login module (ASP.NET) which allows a user either submit username/password (standard “Forms” login) or to click on “Use Windows credentials” link which points to WinLogin.aspx file with windows authentication and disabled anonymous authentication. In case of a success WinLogin.aspx then uses windows username to perform Forms login. It all works nice with IIS (5.1, 6, 7), but I was thinking that your “credentials screening” (using XmlHttpRequest) would be a nice way to hide “Use Windows credentials” link from users who are outside of Windows domain. The only other way is just to check IP address of a user, which is less elegant.

    Sorry for bothering you, I know you’re working for Google now… I’m writing this message using Chrome.

  9. It is 2013 and this solution works just fine. I am glad I found it. Thank you!

    I did modify it a bit though. Replaced XML file with Auth.ahsx module in which I am capturing the domain/username and group assignment for a user authenticated with NTLM. For the rest I am showing the login page with a nice description of the issue, asking for credentials my way and then impersonating that user in the code to access the Auth folder.

Leave a Reply to dimulecCancel reply

Discover more from Dimitri Glazkov

Subscribe now to keep reading and get access to the full archive.

Continue reading