Kerberos Constrained Delegation with ASP.NET
Some security issue may involve kerberos delegation, I have to capture network monitor to check the trace. Therefore, I am going to document the step to configure constrained kerberos delegation with ASP.NET application. The demo environment is in a single contoso.com domain. There are four computers(2012R2):
- dc: the domain controller for contoso.com
- dev: the development computer which has installed Visual Studio
- web1: the web server which has installed IIS
- sql1: has installed SQL Express for double hop demo
Prepare the ASP.NET MVC Application
From Visual Studio, create one MVC web application, select "Windows Authentication" shown below.
For double hop demo later, the application is expected to access SQL on a remote server. We will create a simple class as data model and generate the controller using entity framework.
I have created one simple Product class with Name field only. Run it in dev computer shown below.
Publish to IIS
Next，we will publish the application to web server. If there is any publish error, make sure Web Management Service is started on web server and Web Deploy is installed as well. In this demo, the application is published to DemoApp whose application pool identity is ApplicationPoolIdentity, we will change it soon later.
Change the sql connection string to SQL1\SQLEXPRESS.
In IIS Authentication setting, enable Windows Authentication and disable the others. After this, the app should work and end user can login successfully. While, when access the Products page, there should be login error because currently it is using the "contoso\web1$" computer account to access the SQL Server, and there will be access deny.
Change Application Pool Identity
Our expectation is to use login user's identity to access the SQL Server, in this scenario, IIS identity will be used to decrypt the kerberos ticket. Anyway, both of a machine name or domain account will be good enough for this. While, in load balance scenario, we will need set domain account as IIS identity to make sure all the web servers can decrypt the kerberos ticket from AD.
In IIS Configuration Editor, set useAppPoolCredentials as true, then IIS will understand it will use application pool identity (a domian account contoso\serviceuser configured in last step) to decrypt the kerberos ticket.
Next, we need use setspn utility tool to register SPN for the domain account (contoso\serviceuser). It will be recognized by AD that who is hosting the target service (to decrypt the ticket). After this, the end user should be able to login successfully, though still access deny to access the SQL Server.
In order to delegate the end user's identity to SQL Server, enable "ASP.NET impersonation" in authentication setting (set system.webServer\validation\validateIntegratedModeConfiguration as false to eliminate the validation).
You will notice the below error when access the SQL Server(set system.web/customErrors to Off to see the rich information).
The reason for this error is the domain account is not allowed to delegate the identity to any service yet. If you capture a netmon log on web server, there will be below error traffic. You can use Authentication traffic filter or KerberosV5 protocol directly to filter the trace.
Enable Kerberos Delegation
Go to DC, find the domain account. There will be a Delegation tab (after setspn) now. Check "Trust this user for delegation to any service (Kerberos only)" means the account is allowed to make the delegation. After this setting, it should be successful to access the SQL Server.
Enable Constrained Delegation
Maybe we don't want to enable delegation to all the services due to security concern. In that case, we can enable constrained kerberos delegation (the third option) to limit the scope. In this demo, the SQL Server is running under NT service, i can find all the services belong to computer sql1 and MSSQLSvc/sql1.contoso.com:62520 is my target (62520 is a dynamic port configured in Sql Server Configuration Manager, SQL Server Network Configuration\Protocols for SQLEXPRESS\TCPIP\IP Adresses).
If your SQL Server is running by a domain account instead of NT Service or Local System, you will need setspn for that domain account. If there is anything wrong, try Microsoft Kerberos Configuration Manager for SQL Server to fix it. Lastly, during the test, in order to make sure all the kerberos tickets are fresh instead of from cache, you may also use command "klist purge" to purge the ticket.
Hope that helps.