I recently upgraded from IIS 4.0 to IIS 5.0. The upgrade went smoothly, but users are now experiencing authentication problems. The site is an intranet site, and I had used Windows NT Challenge/Response authentication on the IIS 4.0 server to authenticate users. One reason for moving to IIS 5.0 was to take advantage of Kerberos. I've set up the IIS 5.0 server to use Integrated Windows authentication, but my server isn't using Kerberos to authenticate, even though I have a pure Windows 2000 environment. How can I specify what authentication method I want the server to use?
As you mentioned, a new feature of IIS 5.0 is its ability to use Kerberos, which is the built-in authentication method for Win2K networks. Kerberos has several advantages over IIS 4.0-style NT Challenge/Response authentication: Kerberos is more secure, supports delegation, can be accomplished through a proxy server or firewall, and is faster.
Even so, don't go looking for the Kerberos button in IIS: No such option exists in the UI. The Security tab of the Master Web Properties dialog box for each Web server has an option called Integrated Windows authentication. (The same option exists on the Security Tab for a directory, virtual directory, or file.) However, Integrated Windows authentication isn't really an authentication protocol at all: It's actually two different authentication methods rolled into one. When enabled, Integrated Windows authentication enables both IIS 4.0-style NT Challenge/Response and Win2K-style Kerberos authentication. You can't, however, select which method you prefer from the UI.
When Web servers authenticate Web browsers, the server sends the browser information about the authentication methods that the server can use. The browser then selects the first method it recognizes and responds to the server accordingly. The Web browser and Web server then proceed to authenticate the user according to the mutually selected scheme.
When you set up IIS 5.0 to use Integrated Windows authentication, IIS sends a special header to the browser called the Negotiate header. Microsoft Internet Explorer (IE) 5.x recognizes this header as an offer to choose Kerberos, if possible. A very specific set of circumstances is necessary for IE 5.x to use Kerberos. Basically, IIS 5.0 must talk to a Win2K client for which the Web server is part of the Win2K domain. Only IE 5.x can, at this time, use Kerberos with IIS 5.0.
To address your original question, a particular difficulty occurs when upgrading from IIS 4.0 to IIS 5.0 when you've set the IIS 4.0 server to use NT Challenge/Response authentication. In such a case, the IIS 5.0 installation routine honors the setting and sets IIS 5.0 to use only NT Challenge/Response. IIS 5.0 doesn't offer the Negotiate header to the browser, so the browser doesn't use Kerberos even if the browser can.
Although you can't set the authentication method in the UI, you can set it in the metabase. Use the adsutil.vbs script found in the \inetpub\adminscripts directory to modify the NTAuthenticationProvider registry subkey as follows:
cscript adsutil.vbs set _ w3svc/NTAuthenticationProviders _ "Negotiate,NTLM"
Alternatively, you can use metaedit.exe to make the same edit. Be certain there's no space after the comma in "Negotiate,NTLM", and as always, back up your metabase before you make any changes.
I run an application on IIS 4.0 that uses the Session_onEnd event to trigger cleanup for the application. I've discovered that the event doesn't always fire when a session ends. Some articles and newsgroups state that this problem is a known bug. I can't find any such reference, but clearly Session_onEnd isn't working as expected in IIS 4.0. My tests with IIS 5.0 show that Microsoft has apparently fixed the problem. Can you shed some light on this bug in IIS 4.0?
The problem isn't a bug. Rather, it boils down to a COM threading problem. The answer to your question requires an understanding of how COM components work with various threading models. Details about this important issue are beyond the scope of this article, but IIS administrators should have a keen interest in this topic for several reasons. The chief concern is that COM objects that your system uses (including Microsoft-provided COM objects) can dramatically affect performance and scalability. You can find a good introduction to this topic at http://msdn.microsoft.com/workshop/server/components/daciisperf.asp.
When you create a COM object, it's assigned a threading model. Three threading models exist:
- Apartment threadingOnly one thread from an object can communicate with the server. You can, however, have multiple instances of the object, each with its own thread. This threading model is the only one that the Microsoft Access database engine supports, which is the primary reason Microsoft recommends Microsoft SQL Server as the database of choice with IIS.
- Free threadingAn object can use (spawn) multiple threads.
- Both threadingAn object can be accessed as an Apartment-threaded object or Free-threaded object.
You asked why Session_onEnd doesn't appear to fire in IIS 4.0 but seems to work in IIS 5.0. By default, ADO is marked as Apartment threaded in the registry, which means that one thread is at work for a database access request. In this mode, the thread that creates the ADO object is the same thread that must destroy the ADO object. Let's say that a user makes a query to a database and that database isn't available for 15 minutes. Tired of waiting, the user leaves the page and goes back to downloading MP3 files or whatever he or she was up to. The user session is over, but the thread that must destroy the session isn't available because it's still waiting on the database. Session_onEnd actually fires, but a thread can't destroy the ADO object because the only thread that can do the job is busy. This delay gives the appearance that Session_OnEnd never fired.
This same sequence of events can occur if you try to use Active Server Pages (ASP)-intrinsic objects in Session_onEnd. You can't, for example, use the Response object to send information to the browser because the session is closed. This fact might seem obvious to some, but it eludes more programmers than you might think.
So, how did Microsoft improve this functionality in IIS 5.0? IIS 4.0 trusts the registry setting that says ADO is Apartment threaded, but IIS 5.0 doesn't. Instead, IIS 5.0 queries the component to get its threading model. ADO is really Both threaded, so IIS 5.0 can create the ADO object on one thread, then use another thread to destroy the ADO object. This ability makes the Session_onEnd event appear fixed in IIS 5.0.