I’ve spent a lot of time at a client site recently working on a large complex application migration project. In my scenario, the client is migrating applications from another domain, to their own. There are no domain trusts in place, so you could consider it as an acquisition/merger type scenario.
One of the common challenges often encountered in this type of work is troubleshooting Kerberos authentication process for web apps. Once the concepts of Kerberos authentication are understood, the process is relatively straight forward. However, understanding this seems to be a common issue in many IT environments, especially when the line between a traditional Infrastructure resource (who may be responsible for configuring service accounts and SPNs) and a developer (who may be responsible for configuring the IIS platform and deploying applications) becomes somewhat grey.
I decided to write a blog about my experience… Hopefully this will help you troubleshoot the Kerberos implementation process, whilst also explaining how to share or “federate” your applications with disparate parties.
How do I know if this process is suitable for my environment?
- You have legacy line of business applications which aren’t claims aware.
- You need to share your line of business applications between forests which do not have domain trusts or federation services in place.
- You have an identity available in each domain – given that there are no trusts or federation in place, this is key.
- You just want to know more about Kerberos Authentication and Delegation.
Back to basics – single domain Kerberos authentication process.
Below is a brief explanation of how the Kerberos authentication protocol works in a single domain environment. For more information, read the official Microsoft documentation.
- Client contacts the KDC service saying that it’s a user and requests a ticket to get tickets (TGT).
- KDC issues the TGT to the client by encrypting with the client machine password hash.
- The client requests a service ticket from the KDC TGS, producing its TGT for authorisation.
- Based on the previous authorisation, a service ticket is issued to the client.
- The client presents its service ticket to the application server for authentication.
- Upon successful authentication, client/server session is open. Normal request/response process continues.
The Scenario
In the scenario presented below, we have two companies, each with their own instance of AD DS (DOMAINA and DOMAINB).
- Applications have been migrated from DOMAINA to DOMAINB.
- DOMAINA users are currently being migrated to DOMAINB, therefore they have a user account object in each domain.
- Some users will access applications internally (from DOMAINB). Some users will access applications externally (from DOMAINA).
Now you may be thinking… How will the remote users access applications externally via the internet using the Kerberos authentication protocol?
Good question 🙂
As we all know, Kerberos authentication (generally speaking), does not allow an internet-connected client to authenticate directly. This is because the Kerberos Key Distribution Centre (KDC) role is usually deployed to a domain controller and therefore… it is understandable that we do not want this role accessible from the internet.
Enter Kerberos Protocol Transition (KPT)!!
KPT enables clients that are unable to get Kerberos tickets from the domain controller to pass through a service that “transitions” the client’s authentication into a true Kerberos authentication request.
In the scenario presented above, the KPT role is played by the load balancer or application delivery controller. This is a common feature provided by many vendors in the Application Delivery Controller (ADC) space. For the remainder of this article, this will be referred to as the “Kerberos SSO engine.”
To ensure a pleasant user experience, external users will browse to an application portal, hosted by the ADC in DOMAINB.local. They authenticate ONCE to the ADC and from that point onwards they can access multiple web applications provided by the ADC (which will effectively proxy their credentials to each web application server using KPT).
Internal users will continue to access applications directly.
Putting it all together – Required Components
Now that you understand the scenario, let’s cover off the required components to make the solution work.
Kerberos SSO engine – APPGW.DOMAINB.local | The Kerberos SSO Engine role is played by the ADC. Upon a successful authentication to a web portal, it will proxy users credentials to multiple web applications ensuring a Single Sign On experience.
|
Web Farm – WEBSRV1 and WEBSRV2.DOMAINB.local | The Web Farm is responsible for hosting web applications.
|
Service Principal Names (SPNs) | SPNs will need to be configured for each service account which will run the…
SPNs should always be in the format SERVICE/FQDN and SERVICE/NetBIOS name. This is a simple concept which often causes a lot of pain when troubleshooting Kerberos authentication processes. For example, if you had a website with the host header “prodweb01”, you would configure the following SPNs “HTTP/prodweb01” and “HTTP/prodweb01.domainb.local” on the service account which is responsible for running the application pool in IIS. |
Application Delivery Controller
Whilst it is out of scope for the purpose of this post to document the configuration process of an ADC, it is worthwhile noting that the roles listed below are common features provided by many vendors in the ADC space today.
In my scenario, I used a free trial of an F5 BIG-IP device hosted on Amazon Web Services (AWS) which comes with a deployment guide.
It is also worth noting that AWS also offers a free trial of a Citrix NetScaler which is a competitive alternate to the F5.
The ADC has three primary roles in the scenario presented above:
- To load balance the web farm which will host our web-based applications
- To provide an application portal style page for external users (DOMAINA) to access their web applications – On an F5 device, these are called Webtops. On a Citrix NetScaler, these are called Gateways.
- To act as the Kerberos SSO engine, which will carry out the Kerberos Protocol Transition (KPT) process on behalf of each user.
I will leave it up to you to evaluate which device is the best fit for your organisation, if you already have one of these devices available to you then decision may be that simple :).
Web Farm and Service Account Configuration
In the scenario I presented above, I used two Windows Server 2012 R2 VMs with IIS installed to host my web farm (you guessed it – the VMs were also located in AWS). The web servers were then placed into a server pool on my ADC and presented by a single VIP for load balancing purposes. Finally, I created a dummy website to use as a test page.
Now we are ready to get into the “nuts and bolts” of the Kerberos web application configuration.
Configuration Guide
The following steps assume that you have created a test webpage to perform the configuration on (shown below).
- Launch IIS Manager and select your Website > Authentication.
As you can see above, by default only Anonymous Authentication is allowed.
- Now we need to enable Windows Authentication and disable Anonymous Authentication. This is a common stumbling block I have encountered in the field. If Anonymous authentication is enabled, IIS will always try to authenticate using it first, even if other methods are enabled. You can read more about IIS Authentication precedence on MSDN. Your configuration should now look like the image shown below.
- As you’re probably aware, Windows Authentication providers consist of Negotiate or NTLM. Negotiate is actually a container which uses Kerberos as the first authentication method and then NTLM as fall back (when Kerberos fails). We now need modify our providers to ensure Negotiate takes precedence. Select Windows Authentication > Providers and make sure that Negotiate is at the top of the list as Shown below.
Service Account and SPN Configuration
We are now ready to configure our service account which will run the Application Pool for our test website.
Since we would like to access our website using a custom host header, we need to register a Service Principal Name (SPN). Furthermore, given that our website is operating in a web farm, we are best placed to register the SPN to a domain service account and use the aforementioned service account to run the test website’s Application Pool (on both members of our web farm).
Registering an SPN to a computer account will not work in this scenario given that we have multiple web farm members. Kerberos gets very unhappy when we have duplicate SPNs registered to multiple accounts and because of this, I would STRONGLY advise you to use domain service accounts. One of the things I have taught myself to check first when troubleshooting Kerberos issues is to validate that there are no duplicate SPNs configured (you can do this using the SETSPN -L command).
For the purpose of this example I have created a domain user account called “IIS_Service”. As you can see below, there are currently no SPNs configured on this account.
Note: if you aren’t clear on the exact purpose of an SPN, please do some reading before proceeding.
Now that you are clear on the purpose of an SPN, let’s review the configuration…
Website Bindings (host header): | http://testsite and http://testsite.domainb.local |
IIS Service Account: | DOMAINB\IIS_Service |
Output: | Setspn –S HTTP/testsite IIS_Service Setspn –S HTTP/testsite.domainb.local IIS_Service |
- We are now ready to register the SPNs to the IIS Service account. SPNs should always be in the format SERVICE/FQDN and SERVICE/NetBIOS name. You can do this using the commands listed in the “Output” section of the table above. Once you have run these from an administrative command prompt (with domain admin rights) you should see an output similar to the following…
- It is good practise to verify that the SPN’s you configured have been entered correctly. You can do this by running “setspn –l domain account” as shown below.
Now that we have verified that our SPNs have been configured correctly, we can return to the Website and Application Pool to finalise the configuration.
In the next section we will define the service account (IIS_Service) used to run the website’s Application Pool. IIS will use this service account to decrypt the Kerberos ticket (presented by the client) and authenticate the session.
Application Pool Configuration
- Navigate to the website’s Application Pool:
-
Select Advanced Settings > Browse to Identity and change the service account to IIS_Service
- Validate that the service account entered correctly.
- Navigate to IIS > Sites > Test Site > Configuration Editor.
- From the drop down menu, browse to system.webServer > security > authentication > windowsAuthentication:
- Change useAppPoolCredentials to True.
Note: by setting the useAppPoolCredentials value to True you have configured IIS to use the domain service account to decrypt the clients Kerberos ticket which is presented to the web server to authenticate the session.
- You will need to run an IISRESET command to update the configuration. Unfortunately recycling the Application Pool and Website is not sufficient.
- Test the web application – your browser should have http://*.domainb.local in the local intranet zone to ensure seamless single sign on.
You can validate that Kerberos authentication is working correctly by inspecting the traffic with Fiddler:
This completes the web farm and account configuration.
Kerberos SSO Engine and Delegation Explained
Now that we have successfully configured our web site to use Kerberos authentication we need to configure delegation to allow the ADC to perform KPT (like we discussed earlier in the post).
As you have probably guessed, the ADC also requires a Service Account to perform KPT. This will allow it to act on behalf (proxy) of users to complete the Kerberos ticket request process. This is especially useful when our users are external to the network, accessing applications via a secure portal, as per the opening scenario. (Yes folks, we have almost gone full circle!)
To handle this process, I have created another service account called “SSO_Service.” I have also registered the SPN “HTTP/apps.domainb.local” – as this is the URL for my application portal page (shown on the scenario diagram above).
We are now ready to configure Kerberos Constrained Delegation, but before we go any further I thought I should provide a brief explanation.
In its simplest form, delegation is the act of providing a service account (SSO_Service in my example) with the authority to delegate the logged in credentials of any user to a backend service. That’s it!
In my scenario, the front end service is the web application portal provided by our application delivery controller. The backend service is the web application (Test Site) we have configured. Therefore, upon successful authentication, credentials will be delegated from the web application portal to our backend web applications, providing seamless single sign on experience for our users. This is best represented by the conceptual diagram shown below.
Kerberos Constrained Delegation – Configuration
- Locate the service account you would like to configure delegation access for (SSO_Service in my example) and select the Delegation tab.
TIP: you must have an SPN registered to the service account for the Delegation tab to be visible.
- Select Trust this user for delegation to specified services only > Use Kerberos only.
- Select Add and browse to the service account you would like to delegate to and select the SPN we registered previously.
We have now authorised the SSO_Service account to delegate the logged in credentials of any user to the IIS_Service service account. It is important to remember that the IIS service account only has SPNs configured to access the test website :).
Hopefully this helps you to better understand Kerberos Authentication whilst providing insight as to how you can share secure access to Kerberos web applications externally.
Kerberos authentication process for web apps is very complicated and a long process too. Is there any other easy way of migrating applications from another domain to another? Anyway thanks for sharing.
what should be the SETSPN look like if the website is “http://servername/myteam” should it be
setspn -s http/servername/myteam domain/serviceaccount ?? will this work ?