Delegation is a feature of Kerberos authentication that allows a server to obtain a Kerberos ticket on behalf of an end user without ever having access to the end user's password. This functionality allows Kerberos to solve typical "double-hop" authentication problems where a user's credentials need to flow through multiple levels in an n-tier architecture. Other authentication technologies (Digest and NTLM) do not allow this natively (we'll cover something called "Protocol Transition" later on down the track).

In this simple scenario, we'll add a backend SQL Server to our original simple scenario. Our user will authenticate, using Kerberos, to our web application, and then the web application will open a connection to SQL Server using the end-user's credentials (a "trusted connection").

IIS and Kerberos - a delegation scenario

The delegation functionality featured here can be used through multiple levels (for example if you have a web server, connecting to an application server, connecting to an SQL Server). The delegation done by the web server is repeated at each additional layer in the chain.

In the diagram above the following sequence of events takes place:

  1. The client browser supplies a Kerberos service ticket to the web server. The process that happens in obtaining a service ticket is covered in the previous post.
  2. The web server, seeing the need to open a connection to SQL Server using the end user's credentials obtains the necessary ticket from the KDC
  3. The KDC returns a ticket if the web server is permitted to delegate
  4. The server opens the connection, sending the ticket obtained from the KDC
  5. The SQL Server permits the connection to be opened, or returns a error indicating that the user is not permitted login to SQL Server
  6. The web server returns the web page to the end user

To get this working, we need some additional configuration in addition to what we performed previously. In Active Directory we need to give permission to the web server so as to allow it to get tickets on the end user's behalf. If you locate the web server's computer in Active Directory Users and Computers MMC, right-click and choose "Properties", there is a "Delegation" tab where you can configure the necessary options. The Delegation tab looks different depending on whether you have a Windows 2000 functional level domain, or a Windows 2003 functional level domain.

In a Windows 2000 functional level domain, there is a single checkbox to allow delegation for this server. In a Windows 2003 functional level domain, the dialogue looks like the one below:

Configuring Delegation - Windows Server 2003 functional level domain

The first option (unconstrained delegation) corresponds to the single setting in a Windows 2000 functional level domain. Enabling this setting sets certain bit values the AD UAC attribute for the server's computer account (typically it changes from 0x80 to 0x2080). Alternatively, you can configure "constrained" delegation. Constrained delegation permits the server to get a ticket only for the nominated services. It prevents the server from getting a ticket on behalf of the user to any service in your environment. This can be helpful in the event your server is ever compromised. Using this setting sets the msDS-AllowedToDelegateTo AD attribute for the computer account in question.

Constrained delegation makes available another option (Protocol Transition) - this is the option that is labelled "use any protocol". We'll deal with Protocol Transition, and its implications in another post in the series.

For our scenario, we'll configure constrained delegation to our backend SQL Server. Click the "Add" button, and browse for the relevant computer or user account (I am running SQL Server under LocalSystem, so I would browse for the machine account of the SQL Server). You'll be presented with a list of SPNs for that machine - add the SPN for the SQL Server service. If you are not familiar with SPNs, read Part 2 in this series.

There are a couple of "gotchas" with constrained delegation that you need to be aware of. Firstly, constrained delegation only works if the services are in the same domain. The end user (and their computer's machine account) can be in any domain (or indeed, even in another trusted Forest). However the web server and SQL server, and any other backend servers need to be in the same domain. Secondly, if one hop in the delegation chain uses constrained delegation, then all other subsequent hops in the chain must also use constrained delegation.