ADFS Deep-Dive: Primer
Disclaimer: Some concepts have been simplified until I’m ready to cover them in more detail.
This is Dave Gregory, back from a blogging hiatus. :) This blog series will be an on-going work in progress as I will be adding new sections over the coming weeks and months. This first blog won’t be so deep but the content will continue to get deeper as I unfold and explain the underlying functionality of ADFS. If you would some additional primer content on ADFS, please visit our previous blogs:
FAQ on ADFS - Part 1
https://blogs.technet.com/b/askpfeplat/archive/2013/07/22/faq-on-adfs-part-1.aspx
How to Build Your ADFS Lab on Server 2012 Part 1
Why ADFS?
When I started to pick up ADFS about 24 months ago, most of my customer’s requests where simple, “I want to federate with some application, hosted by some vendor, so that my users can login into this application without being prompted for credentials.” This type of request may seems simple but the power of the SSO experience and the underlying technology is transformative.
As I look back at my career and how the technology has evolved, I realize we’re seeing a paradigm shift in how our customers use technology. For enterprise users, Active Directory was at the core of how they gained access to all those wonderful internal LOB applications. And while this is still somewhat true, in the last six years, we’ve seen an explosion of internet-based software providers (SaaS). Our customers want to consume this software but how exactly are they supposed to grant their users access without having to manage another set of credentials. This is exactly where ADFS fits in. ADFS is opening customer’s minds to the idea of the cloud and all the wonderful applications it has to offer. They get to retain control of their username and passwords while still providing their users access to a broad set of cloud-based applications.
So, what exactly is ADFS? In plain English, it’s a web service that authenticates your users to Active Directory while also simultaneously providing them access to some claims-aware application. Many times, these applications are typically used through the client’s web browser. The applications can be on-premise, off-premise, or even hosted by other companies. It doesn’t really matter where these applications live, who owns them, as long as they can accept a token with claims.
Over the course of this blog, I’m going to go with you step-by-step through the various scenarios where ADFS applies. Covering from this scenario-drive approach, I think, will lay a good foundation for the remainder of the ADFS series.
Scenarios and Authentication “Flow”
The first scenario is the most common, and it’s called Web SSO. Here are some examples of Web SSO:
- You want your users to login to web applications, either off-premise or on-premise, from your browser using their Active Directory credentials. Think SaleForce.com, or Servicenow.com, or SharePoint Online (SPO).
- Another identical example is you want your users to login to O365 from the browser using their Active Directory credentials. Think OWA in O365, SharePoint Online (SPO).
Web SSO while inside the corporate network
Most SSO transactions are browser-based, which we call a passive request. It’s called passive because the browser really isn’t SSO-aware but is still brokering an SSO transaction. In these scenarios, you may not notice it, but the browser goes through a series of redirects to handle the SSO transaction. Here is a high-level view of the traffic flow for Web SSO:
For example, let’s say I want to login to a claims-aware application hosted in Azure, from my browser while inside the corporate network:
I would navigate to https://claimsweb.cloudready.ms and after a few redirects, boom it just logs me right in without any prompts. Wow.
The redirects happened so quickly, you may not even notice them. How do we know that I used my integrated Windows credentials to authenticate to my ADFS server?
We can run “klist tickets” from my client and see that a Kerberos ticket was acquired for my ADFS server: HTTP/sts.cloudready.ms
Everything happened so quickly, how can we confirm that ADFS was even involved in this transaction. We can open fiddler, the HTTP debugger and see all the redirects:
Translation in Layman Speak:
HTTP 302 = Please go to this other URL instead, in this case, the ADFS server.
HTTP 200 = OK, things are good.
Frame 1: I navigate to https://claimsweb.cloudready.ms . It performs a 302 redirect of my client to my ADFS server to authenticate.
Frame 2: My client connects to my ADFS server https://sts.cloudready.ms . My client submits a Kerberos ticket to the ADFS server.
Frame 3: The ADFS server send me back some HTML with a SAML token and a javascript that tells my client to send it over to the original claims-based application – https://claimsweb.cloudready.ms .
Frame 4: My client sends that token back to the original application: https://claimsweb.cloudready.ms . Claimsweb checks the signature on the token, reads the claims, and then loads the application.
Attached below is a fiddler trace of this transaction. If you need to download fiddler, you can find it here:
https://www.telerik.com/download/fiddler
Download The Above Web SSO Fiddler Trace
Key Takeaway: With browser-based SSO, the client’s browser handles the entire SSO transaction through a series of browser redirects and/or HTTP POST’s. The application you want to access never directly talks to the ADFS server because the client browser handles the entire SSO transaction.
Web SSO while outside the corporate network
Now, this “flow” is identical to the example I just gave above with one exception. Since I’m outside the corporate network like most mobile workers, I won’t typically have direct access to a domain controller to get a Kerberos ticket so the experience is slightly different. The difference here is that instead of using the internal ADFS server, I authenticate through the ADFS Proxy/WAP server. The ADFS Proxy/WAP is an edge server that resides in the DMZ and is available for users outside the corporate network. Here’s another high-level view of the “flow”:
I would navigate to https://claimsweb.cloudready.ms, and this time, I’m now prompted for credentials:
After typing in my credentials, I’m immediately back in the application:
Now, this transaction stopped us and asked for credentials so we can see that ADFS was part of the transaction. The fiddler trace would look identical but instead of using my Kerberos token, I typed in my username and password. This is called forms-based authentication (FBA).
To reiterate, the “flow” and fiddler trace would be identical but instead of using Kerberos to authenticate me, I’m asked for my username and password.
Key Takeaway: You could replace the above Web SSO experience with any other web application, whether on-premise or off, and the experience would be identical. Regardless, browser-based SSO is handled through a series of browser redirects and/or HTTP POST’s. With the default configuration, if you are inside the corporate network, you won’t receive any prompts for credentials. If you are outside the corporate network, you will instead get a forms-based login.
Bridging the Gap
So, in the above Web SSO scenarios, how did the token get from the ADFS server over to the claims-aware application? Did the claims-based applications talk directly to the ADFS server get a token?
No, the application doesn’t talk directly to the ADFS server. The client’s browser helped bridge this gap. Once I authenticated to my ADFS server, the ADFS server sent some html back to my client like the following:
<Html><body>
<form method="POST" action="https://claimsweb.cloudready.ms:443">
<input type="hidden" name="SAMLResponse" value="PHNhbWxwOlJlc3BvbnNlIElEPSJfMjg0ZjdiOTAtZWJlNy00MDhlLTliMDMtMzBjNzQ1MmQ4Y2U4IiBWZXJzaW9uj" />
<input type="submit" value="Submit" />
</form>
<script language="javascript">window.setTimeout ('document.forms[0].submit()', 0);</script>
</body></html>
Note: I truncated the SAMLReponse to make this legible.
So the above HTML is returned back to the client’s browser and what exactly does it instruct the client browser to do:
The javacscript at the bottom tells the client browser to POST the SAMLResponse to https://claimsweb.cloudready.ms, which is my claims-based application. BTW, POST in layman’s terms means send. :)
Key Takeaway: The user’s browser brokers the entire transaction and the claims-based application never talks directly to the ADFS server. This is important to remember because one of the core requirements for Web SSO to work is the client has connectivity to both the ADFS server and the claims-based application.
Federated SSO
The following scenarios are examples of Federated SSO. These scenarios aren’t as common but sometimes more valuable because if you’ve ever wanted to collaborate with a partner, another company, or another AD forest, federated SSO is the magic that makes it happen.
You want users from another organization to login to your web applications using their own identity credentials.
You want to login to another organization’s web applications using your own Active Directory credentials.
You want users from another internal Active Directory forest to login to your web applications in your Active Directory using their own AD credentials without a domain and/or forest trust.
You want to use your production Active Directory credentials to login to test web applications located in your test Active Directory environment without a domain and/or forest trust.
You want users to be able to login to your web applications using their Google, Facebook, Live ID, Yahoo, etc. credentials.
For most intents and purposes, federated SSO just a slightly more advanced version of the browser-based web SSO we saw above. Let’s say that your company Cloudready.ms wants to collaborate with Microsoft Corporation. Consequently, both of you stand up ADFS to support this project. Both companies don’t have internal network connections to each other nor any Active Directory trusts but you need your Microsoft users to login to your CloudReady applications. You would federate your two ADFS environments together – that is federated SSO.
The end-user experience is almost the same as the Web SSO we saw above but with one major difference. Since your CloudReady.ms infrastructure may be federated with multiple external partners, when all those Microsoft users go to the claims-based application, CloudReady needs to know what Identity Provider to send them off to for authentication. Consequently, it may ask them a series of questions to figure out where to send them. This question could be a drop-down list of identity providers or ask them for their email address to determine how to route them. This process of asking the user is called Home Realm Discovery (HRD) as you can see here. In previous versions of ADFS, it would display a drop-down list of identity providers. In ADFS 2012 R2, there is also an option to ask the user for their email address to help make this decision:
Upon typing in my email address, CloudReady’s ADFS Proxy redirects me over to my Microsoft’s ADFS Proxy server where I will authenticate via forms-based authentication since I’m working from home today and aren’t inside the Microsoft corporate network:
Upon hitting submit, Microsoft’s ADFS would send back off to CloudReady’s ADFS with a token in tow. After CloudReady’s ADFS proxy processes the SAML token, it will then send me back to the application with another token in tow and I will gain access to the application:
This type of configuration results in a few more redirects for the client browser but enables users from other Active Directory forests, partners, or organizations to login to applications that you own or vice-versa.
Frame 1: I navigate to https://claimsweb.cloudready.ms . It performs a 302 redirect of my client to my ADFS server to authenticate.
Frame 2: My ADFS server is federated with multiple identity providers so it performs Home Realm Discovery and asks me for information so it can route me to the correct identity provider.
Frame 3: Once I select my identity provider, it performs a 302 redirect to https://corp.sts.microsoft.com .
Frame 5: I’m currently external to Microsoft corporate network, so I’m asked credentials using forms-based authentication. After it authenticates me, it sends a SAML token back to my browser with a javascript in the page that tells me to automatically send it back to https://sts.cloudready.ms .
Frame 6: CloudReadyADFS receives the token I sent it and returns another SAML token to my browser and some javascript in the page automatically sends that token back to the original application - https://claimsweb.cloudready.ms .
Frame 7: Claimsweb receives the token, verifies the signature, read the claims, and then loads the application.
Download The Above Federated SSO Fiddler Trace
O365 Flow Scenarios
These two scenarios aren’t browser-based because someone is using either Outlook or Lync thick client to access O365. So although these clients can’t handle all the redirects like a browser can, a lot of things happen behind the scenes that still make this a seamless experience. The “flow” with these scenarios is different so I wanted to take some time to talk about them:
You want your users to login to O365 from Outlook thick client using your Active Directory credentials.
You want your users to login to O365 from Lync thick client using your Active Directory credentials.
The Outlook client is completely unaware of ADFS and SSO. It just knows the mail server to connect to, the username, and the password, nothing more. The nice thing is that the Outlook experience is identical whether I’m inside or outside the corporate network. I open Outlook and configure it with my username and password, and it just works:
Since we’re not using a browser, there is no concept of redirects so how exactly does Outlook handle SSO to O365?
The answer is that O365 actually handles the SSO transaction for the client. Outlook connects to O365 with your username and password. O365 determines that you are a federated user and O365 connects to your ADFS proxy server or WAP server to get a token on your behalf. This way, Outlook doesn’t have to know anything about ADFS or SSO. Kind of cool how this all works together to create a pretty seamless experience, huh?
https://sts.cloudready.ms/adfs/services/trust/13/UsernameMixed
Key Takeaway: The Outlook thick client has no clue what SSO is. O365 is smart enough to go to your ADFS Proxy and get a token on the user’s behalf. But this means that if you plan to use Outlook and your email is in O365, you must have ADFS Proxy servers and they must be online when the user tries to sync their email.
Active Requestor Client – Lync
We call Lync an active requestor client because Lync is typically ADFS/SSO aware and talks to the ADFS server directly to get a token that it can use to connect to O365. I won’t get into the details about how this works but you have to create some DNS records in your internal and external DNS so that Lync knows whether it’s “internal” or “external” and handles authentication to the ADFS Server/Proxy accordingly.
If I’m inside the corporate network, all I have to do is type in my username and it works:
If I’m outside the corporate network, I will have to type in my Active Directory username and password for Lync to properly authenticate me:
Key Takeaway: Lync is considered an active requestor because it is aware of how to interact with ADFS to get a token, which it then uses to authenticate to O365. O365 does NOT get a token on behalf of the Lync client.
I excluded one scenario flow from this blog because I want to discuss it more in depth in a later post: OAuth 2.0 support in ADFS 2012 R2.
Why Am I Starting Off Like This?
Now, why in covering a primer of ADFS did I focus so much on the end-user experience and the flow? For three reasons:
From being onsite with so many customers, I learned that if you start off with how the end-user will experience ADFS and SSO, it helps frame what ADFS can do and can’t do. I can literally see my customers creating mental “buckets” based on these scenarios and when they start to learn more about ADFS, they will start to organize specific topics, features, or techniques into these scenario “buckets”.
From starting from this end-user perspective, people seem to understand ADFS better when you start to explain it at a deeper level. See bullet point #1. ;)
And lastly, and most important for those that have to support this infrastructure, if we fully understand how each of these scenarios work, we know where to start troubleshooting if things stop working.
Now that covered a primer on ADFS, I’ll start going deeper through a series of blog posts over the coming weeks. Stay Tuned!
David “I’m back” Gregory