In this series’ previous article, I explained that double-hop authentication using NTLM protocol is not possible. I also presented one alternative solution using delegation that was limited, however, only to Windows 2000 native mode Active Directory domains. In this article, I’ll discuss other solutions that can be used to bypass the “double-hop” limitation in environments where NTLM is still prevalent.
Marcin Policht’s third article in the ‘Accessing Active Directory via Active Server Pages’ series discusses several solutions that can be used to bypass the ‘double-hop’ limitation in environments where NTLM is still prevalent.
Let’s start by noting that this limitation does not just affect access to Active Directory from ASP pages; it applies to many other scenarios as well. For example, you will encounter it when using ASP to connect to SQL Server configured with integrated security (the Integrated Security mechanism passes a login name and password to a Windows domain controller for verification, rather then relying on a list of logins stored internally in one of the database tables). You might also run into it when trying to use WMI to launch scripts on a remote system. Such scripts run fine (assuming you have the proper permissions on the remote system) as long as they do not attempt to make network connections. For example, WMI is capable of remotely installing Windows Installer applications. Without delegation, however, such installation will run properly only if the source files for this application reside locally on the same system. If you want to find out more (including the sample script and possible workarounds), you can refer to one of my earlier articles Installing Windows Installer Applications using WMI.
Now that you understand the scope of the problem, let’s take a look at several solutions we can use (outside of delegation and placing the username and password directly on the page in clear text format, which were presented in the first two articles).
The first set of solutions is based on alternative authentication options available in Internet Information Server. Until now, we have been looking solely at integrated Windows authentication. This option, suitable for clients running Internet Explorer and operating within a Windows domain environment, passes the credentials of the logged on user who wants to access a Web page to a domain controller. If the domain controller successfully validates the user name and password, the user is able to open the page. The Script on the page runs locally on the IIS server in the security context of the user who opened it; however, no network connections initiated from it are possible unless delegation is used.
ASP pages can also be configured to use anonymous access as an authentication mechanism. With this type of authentication, geared towards Internet Web servers, clients’ usernames and passwords are not checked. Instead, the level of permissions is the same for everyone and is determined by permissions granted to a single account. This account can be set on the Web Site, Web application, or even a single page level. By default, this is the non-privileged local account created automatically when Internet Information Server is installed, called IUSR_MachineName (for example,, for the Web server called SWYNKPC this account would be IUSR_SWYNKPC). Its password is random and managed internally by the IIS. In this type of configuration, remote authentication options are the same as when using integrated Windows authentication, i.e. no network connections are possible.
This situation changes if you replace the IUSR_MachineName account with a domain account and clear the checkbox “Allow IIS to control password” on the Authentication Methods dialog box of the Web Site, Folder, or Web page properties. If you do so, anonymous authentication will be able to use the account you specified not only locally but also for remote connections.
Our first solution is based on combining these two authentication methods (Windows integrated and anonymous) and splitting the authentication process between two separate Web pages. This will authenticate users who want to run the script. We can ensure that only specific users will be able to access it by creating a Windows group, adding all entitled users to it, and finally granting NTFS read permissions on this page to the newly created group. The only relevant code on the first page would be the redirect statement, which would automatically point the browser of all successfully authenticated users to the second page. Redirection is accomplished through a Response.Redirect statement that takes as its parameter the name (and location, if other than the same folder as the first page) of the second page that users are redirected to. For example, assuming that the second page is called ListADGroups.asp, the first page can be as simple as:
The second page would contain the actual script to run and would be configured with anonymous authentication. The account to be used for the anonymous access would have sufficient rights to Active Directory to properly run the script. Note that there is no “double hop” in this case, since the query for Active Directory information originates on the Web Server (from the second page) with the new user account and password information.
You might wonder whether this solution introduces a security risk — after all, what prevents someone without authorized domain account from accessing the second page directly? Of course, that “someone” would have to first figure out what the page name is; still, “security through obscurity” is typically not a good idea. There are a number of options you can use with varying degree of sophistication and efficiency to resolve this issue. Probably the simplest one is the use of ASP session level variables (or some form of custom cookies). You can set the session level variable to a particular value on the first page, verify its value on the second, and process the script only if verification succeeds. For example, you could modify the first page:
Then on the second page, you could include the following code at the beginning of the script:
Our second solution takes advantage of Basic Authentication (or the more secure Digest Authentication if you are running Internet Information Server 6.0 — included in Windows .NET server). Basic Authentication is also not subject to “double hop” limitation; however, it is much less secure than integrated authentication. You can remedy this by running HTTP over Secure Sockets Layer, although implementing SSL will require you to obtain certificates. For intranet Web sites, you can use Microsoft Certificate Server, which is included on Windows 2000 server platform (introduced originally as part of the Windows NT 4.0 Option Pack). For Internet Web sites, you will have to resort to purchasing certificates from such vendors as Verisign or Thawte.
The optimum (although also the most complex) solution is placing the code in the COM object and configuring it as a COM+ application using the Component Services utility (part of Administrative Tools). COM+ applications can be configured to operate as an arbitrarily chosen domain account (using entries on the Identity tab of the COM+ application properties), which will provide appropriate authentication from the ASP page to a remote server (Active Directory domain controller in our case). This, however, is based on creating a custom COM object, for which you need to use programming languages such as Visual Basic, C, C#, etc. I will describe this solution in more detail in my next article.