Kerberos authentication and Application Request Routing
By Adrian Rienzi
This walkthrough will guide you through how to configure Kerberos authentication for multiple back-end applications published by a Reverse Proxy with Application Request Routing (ARR).
Prerequisites
To run this walkthrough, you must have the following:
- IIS 7 or above with ASP.NET role service enabled.
- URL Rewrite Module version 2.0 or above installed.
- Application Request Routing version 2.5 or above installed
To install ARR and all its components in the appropriate order, use the Microsoft Web Platform Installer by clicking on the link at the top of the page. Alternatively, read the following blog post for instructions on installing ARR manually: Installing ARR manually without WebPI.
Introduction
By using URL Rewrite Module and Application Request Routing you can implement complex and flexible load balancing and reverse proxy configurations.
Some time ago, I had to deal with a customer’s scenario where ARR was used as a reverse proxy to make available several internal web applications to internal users.
Customer wanted internal users to browse Web applications through ARR and then it forwarded the requests to the correct Web applications for processing. Back-end applications used IIS integrated authentication. The following figure illustrates the reverse-proxy scenario:
Figure 1. Architectural diagram showing ARR configuration for using authentication
Assuming that the ARR server URL has a name as https://ARR, each web application should be accessed by using these URLs: https://ARR/sales/ and https://ARR/payroll/ .
When a request is made to https://ARR/sales/default.aspx, ARR forwards these requests to an internal server using the https://APP2/sales/default.aspx URL. Similarly, requests to https://ARR/payroll/ default.aspx are forwarded to https://APP1/payroll/default.aspx.
Let’s say AD domain name is mydomain.com. I omitted server’s suffixes for simplicity.
In addition, Internet Explorer setting has been changed to require explicit authentication for every security zone. Then detailed authentication events are recorded on client machine Security Event Log.
Accessing the Web Sites
After having publishing Web applications by following Reverse Proxy with Application Request Routing (ARR) article, when browsing for example https://ARR/payroll/default.aspx, browser asked for authentication. Typing credentials three times, the following message was displayed:
Not Authorized
HTTP Error 401. The requested resource requires user authentication.
Looking at Security Log on user machine and domain controller respectively, it could be seen a service ticket for name ARR$ was requested.
User machine:
Event 4648
Account Whose Credentials Were Used:
Account Name: adrian
Account Domain: mydomain.com
Target Server:
Target Server Name: ARR.mydomain.com
Additional Information: HTTP/ARR.mydomain.com
Domain controller
A Kerberos service ticket was requested.
Account Information:
Account Name: adrian@mydomain.com
Account Domain: mydomain.com
Service Information:
Service Name: ARR$
Service ID: MYDOMAIN\ARR$
It seems a common double-hop scenario would be easy to solve just creating the following SPNs on APP1 and enabling Kerberos delegation on ARR server:
setspn –S HTTP/ARR APP1
setspn –S HTTP/ARR APP1.mydomain.com
For more information about Kerberos double-hop and delegation, see https://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx and https://blogs.technet.com/b/askds/archive/2008/11/25/fun-with-the-kerberos-delegation-web-site.aspx.
But, what would it happen with APP2? If same solution was applied, SPNs would be duplicated and authentication would fail. Duplicate SPNs result in authentication failures.
Configuring the solution
In this section you will configure the solution guarantying:
1) Kerberos authentication
2) SPNs uniqueness
To assure SPN uniqueness, I did the following:
- Create a DNS Host (A) record for every application. This record must point to ARR server IP address. You cannot use CNAMEs because they are resolved to the original ARR name.
For example, create a record named sales for Sales application and a record named payroll for Payroll one. So, to retrieve Sales and Payroll applications, you should browse https://payroll/payroll/default.aspx and https://sales/sales/default.aspx respectively. Although it would be possible to tune URL Rewrite rules to use a friendlier URL such as https://payroll/default.aspx or https://sales/default.aspx I won’t cover that here .
To test this record, just ping the name, for example ping payroll should retrieve:
C:\ping payroll
Pinging payroll.mydomain.com [192.168.2.51] with 32 bytes of data:
Reply from 192.168.2.51: bytes=32 time<1ms TTL=128
C:\ping ARR
Pinging ARR.mydomain.com [192.168.2.51] with 32 bytes of data:
Reply from 192.168.2.51: bytes=32 time=1ms TTL=128
- Register HTTP service SPNs on application servers. You must register a SPN for every name used to reach the application:
setspn -S HTTP/APP1 APP1
setspn -S HTTP/APP1.mydomain.com APP1
setspn -S HTTP/payroll APP1
setspn -S HTTP/payroll.mydomain.com APP1
setspn -S HTTP/APP2 APP2
setspn -S HTTP/APP2.mydomain.com APP2
setspn -S HTTP/sales APP2
setspn -S HTTP/sales.mydomain.com APP2
- Configure Kerberos Constrained Delegation on ARR server for services:
HTTP/sales
HTTP/sales.mydomain.com
HTTP/payroll
HTTP/payroll.mydomain.com
Verifying the solution
In this section of the walkthrough, you will verify if the solution works:
- From a client workstation, browse for example https://payroll/payroll/default.aspx. Application should open.
- To verify if Kerberos authentication is being used, as Administrator, look at Security Log on client workstation and domain controller respectively, you should see events similar to the ones below.
Client workstation:
Event 4648
Account Whose Credentials Were Used:
Account Name: adrian
Account Domain: MYDOMAIN.COM
Target Server:
Target Server Name: payroll.mydomain.com
Additional Information: HTTP/payroll.mydomain.com
Domain controller:
Event 4768
A Kerberos authentication ticket (TGT) was requested.
Account Information:
Account Name: adrian
Supplied Realm Name: MYDOMAIN
User ID: MYDOMAIN\adrian
Service Information:
Service Name: krbtgt
Service ID: MYDOMAIN\krbtgt
Network Information:
Client Address: 192.168.2.50 -> Client IP address
Client Port: 49430
Event 4769
A Kerberos service ticket was requested.
Account Information:
Account Name: adrian@MYDOMAIN.COM
Account Domain: MYDOMAIN.COM
Service Information:
Service Name: APP2$
Service ID: MYDOMAIN\APP2$
Network Information:
Client Address: 192.168.2.50 -> Client IP address
Client Port: 49431
Event 4624
An account was successfully logged on.
Logon Type: 3
Impersonation Level: Impersonation
New Logon:
Security ID: MYDOMAIN\adrian
Account Name: adrian
Account Domain: MYDOMAIN
Network Information:
Workstation Name:
Source Network Address: 192.168.2.51 -> ARR server IP address
Source Port: 49625
Detailed Authentication Information:
Logon Process: Kerberos
Authentication Package: Kerberos
Transited Services: -
Package Name (NTLM only): -
Key Length: 0
- You should be able to navigate application.
Summary
In this walkthrough you have learned how to configure Kerberos authentication for application published through a reverse proxy implemented with URL Rewrite Module and Application Request Routing.
Comments
- Anonymous
March 27, 2017
Hi @AdrianI have http://ARR for hide two App servers (APP1, APP2) But in your solution user must use http://payroll/payroll/default.aspx for access to Payroll App and http://sales/sales/default.aspx for access to Sales App How can I make working http://ARR/sales/default.aspx and http://ARR/payroll/default.aspx with kerberos? - Anonymous
May 23, 2017
Hi @Adrian,I'm also searching for a practical solution to use an IIS as a reverse proxy where the backend servers use Windows integrated authentication.The problem with this solution is, that it ignores the intention to use a reverse proxy in the first place: in my experience, the most common use case for a reverse proxy is to use it as a "facade" in front of several different hosts. One technical reason might be, to avoid that the client uses CORS - some clients have issues with it, which make it impractical to use. This is the case, if you have for example a rich client application running in the browser, which has to access multiple backends (REST APIs). If there is only one host from the clients point of view (the reverse proxy), then there is no need for it to use CORS.But the backends will get requests with a Kerberos ticket with the proxy hostname and will deny to accept it. Setting a SPN with this hostname as an alias for multiple backends obviously doesn't work...