ADFS Deep-Dive: Comparing WS-Fed, SAML, and OAuth

David Gregory back again for another blog on federation and sign-in protocols. Explaining federation so that people can truly understand it isn’t easy. There are a lot of moving parts, various technologies, and sea of acronyms that many times don’t make sense. When I first started learning about federation, I was drowning in these acronyms that I didn’t know anything about. It wasn’t until I started figuring out what they meant and started piecing them together that my understanding of federation finally started to crystalize. I’ve been working really hard to write this stuff and “unfold” this topic in a way that makes sense and really lands with you guys.

The first two terms I started to hear when I picked up federation were WS-Fed and SAML. Being an Active Directory guy, I initially assumed that SAML was somehow related to the SAM database. Ha. Fortunately, those days are past and I want to take all my experiences from the field with customers and distill them down into relatively easy concepts that even my mother could understand. Ok, that’s probably a stretch but you get my drift. J

In my earlier post from back in August, I talked about the various scenarios that ADFS fits into – Web SSO, Federated SSO, and Active/Passive Requestors. That was a pretty high-level overview.

http://blogs.technet.com/b/askpfeplat/archive/2014/08/25/adfs-deep-dive.aspx

Now, we’re going to go a little deeper into WS-Fed, SAML, and OAuth which are the things that tie these disparate systems and applications together.

 

Real-World Analogy

Before we get technical, let’s kick this off with something completely non-technical. As engineers, we have very keen minds about breaking things down into components and processes. This helps us understand things so we can troubleshoot, or build complex systems. When you go to the airport to board a flight, what is your sign-in protocol, authentication protocol, and token type? These three components will be focus of this entire blog. Here is how I would define them:

  • What is the Sign-in protocol? I go to the one of those check-in kiosks, then print my boarding pass, then go through TSA line, then go to the boarding gate, and finally board the plane. It is expected that I interact with the airport in this fashion and performs these actions in sequence, otherwise, I will not get on my plane.
  • What is the Authentication protocol? While my boarding pass is part of this, I have to provide my ID or passport to prove who I am.
  • What is the Token Type? My boarding pass is my token to get on the plane.

Now when we talk about WS-Fed or SAML, always ask yourself those same questions: What is the sign-in protocol, what is the authentication protocol, and what is the token type. Asking these questions will make the difference whether you understand these concepts or not.

Something to mention before you proceed – Don’t try to over analyze the technical details below by picking apart the values of each URL parameter and trying to understand what they mean yet. As we start to get deeper into each of these sign-in protocols in subsequent blogs, picking these apart will make more sense. For now, just try to understand the differences between the terminology and the sign-in protocols.

 

WS-FED

WS-Fed is a sign-in protocol, which in plain English means that when the application you’re trying to gain access to redirects you to the ADFS server, it has to be done in specific way (WS-Fed) for the process to continue. Let’s give some easy examples in line with my example above.

Sign-In Protocol

I go to https://claimsweb.cloudready.ms/. It determines that I’m not authenticated and redirects me over to my ADFS server for authentication but the parameters it sent in the URL conform to the WS-Fed sign-in protocol:

https://sts.cloudready.ms/adfs/ls/?wa=wsignin1.0&wtrealm=https%3a%2f%2fclaimsweb.cloudready.ms&wctx=rm%3d0%26id%3dpassive%26ru%3d%252f&wct=2014-10-21T22%3a15%3a42Z

Let’s break-out these parameters:

  • Wa=signin1.0: This tells the ADFS server to invoke a login for the user.
  • Wtrealm: This tells ADFS what application I was trying to get to. This has to match the identifier of one of the relying party trusts listed in ADFS.
  • Wctx: This is some session data that the application wants sent back to it after the user authenticates.
  • wct: This is the exact time I tried to gain access to the application.

As soon as I see URL parameters like WA, WTRealm, etc, I immediately know that this is the WS-Fed sign-in protocol. Consequently, to hand the user off to the ADFS server properly, the application has to send all of these URL parameters. The URL parameters don’t have to be in this exact order but they must all be present so ADFS knows what to do.

Authentication Protocol

Now, when I get prompted for credentials, what is the authentication protocol: Forms-based.

Token Type

And lastly, after typing in my credentials, what is my token type that ADFS gives me to send back to the original application: When the WS-Fed sign-in protocol is used, ADFS will always issue a SAML 1.1 token back to your browser, which you then automatically POST back to the application.

Click here to download a SAML 1.1 token

Summary: This application is WS-Fed sign-in protocol compliant as is ADFS. I used forms-based login as my authentication protocol, and was issued a SAML 1.1 token type.

 

SAML

SAML is a sign-in protocol and a token type. Tricky, huh. 🙂 In regards to sign-in protocols, SAML and WS-Fed achieve the same thing but handle it very differently. Let’s give another example.

Sign-In Protocol

I go to https://shib.cloudready.ms. It determines that I’m not authenticated and redirects me over to my ADFS server for authentication but the parameters it sent in the URL conform to the SAML sign-in protocol:

https://sts.cloudready.ms/adfs/ls/?SAMLRequest=jZFRT4MwFIX%2FCun7KC3OjWaQ4PbgkqlkoA%2B%2BmAKdNCkt9hZ1%2F14GmkwfFl%2Fv%0APfc7p6cr4K3qWNq7Ru%2FFWy%2FAeZ%2Bt0sDGRYx6q5nhIIFp3gpgrmJ5erdj1A9Y%0AZ40zlVHISwGEddLotdHQt8Lmwr7LSjzudzFqnOuAYQyNLP1Kmb62gtdHvwWc%0AD6PSKOEaH8DgE5ni7CEvkLcZokjNT9AzhIM%2FBF4fACvAyNtuYvRSRSIiZXlN%0AwrlY0CriSxKGhNLDFeXhYjkfZAC92GpwXLsY0YCEM0JnQVQESxaEjCyekZd9%0AP%2BxG6lrq18stlJMI2G1RZLMp%2FJOwMAYfBChZnbpko7E9a%2Fcylv9UipJ%2FFbjC%0AZy6TZcfuB%2Bx2kxklq6OXKmU%2B1sOpEzEiCCfTye%2FfT74A%0A&RelayState=cookie%3A29002348&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=M0xoWQfcN3Yp94T2HiqIdJzEkxYqGc6hhopqi8xOI%2B2BtPSLufFDdQIF7z6Xjm6XdLq1MH9Av5xz2QWYs84ZYhlG3fHtZCjjaoI2wZqplRszHla%2BjtZoW20NGDepDsCRT0AKNkhe%2B4Yj3LshrM6EX5O3obx2Mypy8EcsoURkTF3kf1dwKqsGA3ka7ehbRmUQGJUXD0u4iFBog7YgkL4Q9FYMTanZeRo2X4%2FkAeNxT8ormKWJfYnAzg0F4Ku60zDd5N7jYu4XeyOsXDthEFI5H4WYucAprREl2hgSUI21J782kKzrslalIaJ5BKPIO50NPCIb5Sf6Zw4maLpZrFEfrw%3D%3

Let’s break-out these parameters:

  • SAMLRequest: This is actually a Base64 encoded XML document. You can actually paste this value minus SAMLRequest= into here to decode it and view it in plain text @ https://idp.ssocircle.com/sso/toolbox/samlDecode.jsp
  • RelayState: Session data that the application wants sent back to it after I authenticate against ADFS.
  • SigAlg: Which signature algorithm was used to sign the request.
  • Signature: The digital signature of the request above.

With URL parameters like SAMLRequest, Relaystate, SigAlg, and Signature, this thing has the SAML sign-in protocol written all over it.

Authentication Protocol

This time, when I login into https://shib.cloudready.ms, I’m not prompted for credentials at all so I must have used my Windows Integrated credentials. One way to check to see whether I used Kerberos is to run “klist tickets”:

Yep, my authentication protocol definitely was Kerberos.

Token Type

ADFS will always issue a SAML 2.0 token for an application that is configured with the SAML sign-in protocol.

Click here to download a SAML 2.0 token

Summary: This application is SAML sign-in protocol compliant as is ADFS. I used Kerberos as my authentication protocol, and was issued a SAML 2.0 token type.

 

OAuth

While there is some debate about OAuth being a sign-in protocol or an authentication protocol and while it definitely is evolving, within the realm of ADFS 2012 R2, OAuth is another sign-in protocol.

Sign-In Protocol

I open up a modern application on my Windows 8.1 tablet and when I do, the applications submits the following URL to the ADFS server:

https://sts.cloudready.ms/adfs/oauth2/authorize?response_type=code&client_id=3fb2a37f-4ced-409c-937c-dddd776f4dfd&redirect_uri=https://www.davetestapp.com&resource=https://www.davetestapp.com

Let’s break down these parameters:

  • response_type:  tells that ADFS server that I want to perform OAuth and get an authorization code in return.
  • client_id: The ID of the application I’m trying to get to.
  • Resource: the URL/URI of the application I’m trying to get to.
  • redirect_uri: Tells ADFS who to POST the auth code back to

 

Authentication Protocol

Based on these URL parameters, this is definitely the OAuth sign-in protocol. Upon the ADFS server receiving this request, it prompts with forms-based authentication asking me for credentials. There is a component built into Windows 8.x called the Windows Authentication Broker (WAB) that renders the forms-based sign-in you see below. In this case, the application never saw my username and password because the WAB handles it on behalf of the application.

Source: http://www.cloudidentity.com/blog/2013/07/30/securing-a-web-api-with-windows-server-2012-r2-adfs-and-katana/

Once I authenticate, the ADFS server responds with an authorization code. BTW, this is a one-time use code. You’ll never see this code, but the application will store this to later get an access token, which it can then use to get the necessary user data the application requires.

ms-app://s-1-15-2-1101140336-4090662585-1905587327-262951538-2732256205-1306401843-4235927180?code=AAAAAAAAAAAAAAAAAAAAAA.lxt7fs590QgJAJqMtW9C8KN6tLE.SzhnV-R4lbKXj46nwIbFUm6SLnyryJNE72eg3797LwkSfFQsSNpr7E9sUlCYBH52xvLZDAbwwu7qXCMlqCuVciQ0j3P3-l3ep_lOSJOD3LnwDnXb3MPM1UUNcGLxxVeJmeYhEr15BasdkWqGzTYrCJKf4jbdVT0qb4HKEhpD2aQCDwqjeFF8mNwfne_KL1Ve6ZTNwBWS41SauUnbCTM9qzx-MCDWKEPrLmRR14hCxIsaWfrHmiEYbfl4JXyGcJvhUyffcL-UVwJsQSBjHGlbQXlwrb-ejvvZ6me3YC8CLoS2pvXAMzbppBfg8YAJbGzBPNplbkjM10A7OKifLT4yqQ

This highlighted section is an auth code that the application can then use on subsequent requests to get an access token on my behalf.

 

Token Type

Now the application needs to get some application data on my behalf so it can populate the application appropriately. It takes this above code and performs a POST to the following URL:

https://sts.cloudready.ms/adfs/oauth2/token/

Method: POST

With Parameters:

  • code=<Above Authorization Code>
  • redirect_uri=https://www.davetestapp.com
  • grant_type=authorization_code
  • client_id=3fb2a37f-4ced-409c-937c-dddd776f4dfd"

Note: I didn’t include the Access Code above for brevity.

And guess what it receives it return, an access token:

{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImpIUVEzOS1fVGRuSzRqTlJvbnJZYTF2a0pIWSJ9.eyJhdWQiOiJodHRwczovL3d3dy5kYXZldGVzdGFwcC5jb20iLCJpc3MiOiJodHRwOi8vc3RzLmNsb3Vkcm

VhZHkubXMvYWRmcy9zZXJ2aWNlcy90cnVzdCIsImlhdCI6MTQwNzE3MjQ4OSwiZXhwIjoxNDA3MTc2MDg5LCJlbWFpbCI6ImRncmVnQG1pY3Jvc29mdC5jb20iLCJ1cG4iOiJkZ3JlZ0BjbG91ZHJlYWR5LmludGVybmFsIiwiYXV0a

F90aW1lIjoiMjAxNC0wOC0wNFQxNzoxNDo0OC44NTZaIiwiYXV0aG1ldGhvZCI6InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0IiwidmVyIjoiMS4wIiwiYXBwaWQ

iOiIzZmIyYTM3Zi00Y2VkLTQwOWMtOTM3Yy1kZGRkNzc2ZjRkZmQifQ.bkMvnIJaB6DRdyCiTLsxsTPtvqGydcAmsXQjEumMjH4lN75jx2uCCLg44PU-aXSHZ6R-dOth1iqD-Lf-xy4SKw0O0Z5_oQhPn-3-H0DII3SxtDuR5vrBObKVc-DT8HGxEPQqPPB5EyF_H21fJ_cqjz-dNyVXK_WoTbM1gQf44Lz5250NjFKjIA1M4sG8bjh-mjoHZMhR3SwtixCNmQKqYai_8S5KZz1Srg1olGprwRDbTNVdzh7Qv0vg1RgaejF3i1J-kWmf2Zx_PVQflTAfzu01BUvAiQCOK7-V4RsduEOTSEl9SYVt2E8pvkUrmNdohVKVWopfOK3r0zXZwTYT4w","token_type":"bearer","expires_in":3600}

Components of Access Token separated by a period (.)

  • Header
  • Encoded JWT
  • Digital Signature of JWT

If I Base64 decode the highlighted section above, I can see the JSON Web Token (JWT) in its full glory:

{"aud":"https://www.davetestapp.com","iss":"http://sts.cloudready.ms/adfs/services/trust","iat":1407172489,"exp":1407176089,"email":"dgreg@microsoft.com","upn":"dgreg@cloudready.internal","auth_time":"2014-08-04T17:14:48.856Z","authmethod":"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport","ver":"1.0","appid":"3fb2a37f-4ced-409c-937c-dddd776f4dfd"}

Summary: Now, that was pretty technical, but what does it highlight? We used the OAuth sign-in protocol, forms-based authentication was our authentication protocol, and our token type was JSON Web Token (JWT)

 

Are you picking up on a theme here? These three examples highlight why we like to call these scenarios “The Flow” when speaking about federation. It’s because the sign-in protocol will dictate the overall “Flow” of the scenario – How we should interact with the ADFS server, what parameters it requires, what exactly we are expecting in return.

Besides picking apart URL parameters or trying to capture them with Fiddler, how do you know whether your federated applications are configured for WS-Fed, SAML, or OAuth? Well, there are a couple of ways.

 

ADFS PowerShell

If you output the configuration of each relying party trust (application), it will tell you whether WS-Fed or SAML are enabled for this application:

Get-ADFSRelyingPartyTrust –Name <Friendly Name>

For example, Get-ADFSRelyingPartyTrust –Name “Microsoft Office 365 Identity Platform”

You’ll notice that this relaying party application has both WS-Fed and SAML enabled but what is the effective sign-in protocol?

 

Relying Party Trust Endpoints Tab

The configuration of the endpoints on the actual relying party trust dictate whether the WS-FED or SAML will be used when interacting with this application:

This one only has a WS-Federation Endpoint configuration, which means it can only use WS-FED sign-in protocol:

 

 

Here is another one that has a SAML endpoint configured, which means it can only use the SAML sign-in protocol:

 

Well, what about OAuth then? You’ll notice that this relying party application doesn’t have any endpoints, what gives?

 

Well, to view and configure OAuth on a relying party application, you have to go back to PowerShell:

Get-ADFSClient

 

 

Mixing and Matching?

While in theory you can mix and match sign-in protocols, authentication protocols, and tokens types, in practice you wouldn’t want to do this. Of these three, the one you might see change depending on the circumstances is the authentication protocol. I.E. – Outside the firewall forms-based, inside the firewall Kerberos, or perhaps a specific application wants ADFS to enforce certificate-based authentication.

WS-Fed is actually token agnostic but ADFS was written so that WS-Fed will always reply with a SAML 1.1 token.

So here is the breakdown:

  • WS-Fed Sign-In Protocol = SAML 1.1 Token
  • SAML Sign-In Protocol = SAML 2.0 Token
  • Authentication Type = Forms-Based, Kerberos, NTLM, Certificate, MFA, etc.

 

Which One Should I Use?

For WS-Fed or SAML, it really boils down to the web application that you want to onboard to ADFS. Each vendor may support different sign-in protocols but if the application is based on Windows Identity Foundation (WIF) or is a Microsoft-supported web application (SharePoint, Azure, Dynamics CRM), it will more than likely be WS-Fed. Most other SaaS providers and/or web applications will support the SAML sign-in protocol. ADFS 2012 R2 currently only supports the OAuth authorization code profile, which should only be used for Modern/Metro/IOS/Android applications.

 

Why does any of this matter?

Because after you stand-up ADFS, people will start knocking on your door telling you how they want to federate with some cloud-based application and one of your first questions to them should be:

          Is the application claims aware and does it support either WS-FED, SAML, or OAuth?

 

This is a perfect segue into my next blog, which is what questions should you be asking when installing and configuring ADFS or configuring federated applications. Stay Tuned.

Dave “Ghost Protocol” Gregory

Next Part in the Series: http://blogs.technet.com/b/askpfeplat/archive/2014/11/24/adfs-deep-dive-planning-and-design-considerations.aspx

SAML2.xml