ADFS Deep-Dive: Onboarding Applications

I’m back with the onboarding of applications post I promised. Of all my ADFS work I’m performed over the last several years, the one reoccurring pain point that customers have is onboarding applications to ADFS. The reason this typically happens to because the ADFS admins don’t usually know what the application owners needs and vice-versa. Being the guy that can translate the requirements between the ADFS team and the application owners really is a valuable skill and that’s why I wrote this blog. My goal here is to get your well-versed in what is required by ADFS and what is required on the application side regardless of whether the application is on-premises, off-premises, SAML, or WS-Fed. If you need a primer on the differences between SAML or WS-Fed, please check out on of my prior posts:

http://blogs.technet.com/b/askpfeplat/archive/2014/11/03/adfs-deep-dive-comparing-ws-fed-saml-and-oauth-protocols.aspx

Breaking it Down

If you break down a browser-based SSO transaction, you will quickly see some of these things are required. If you read my previous ADFS Primer post, then most of this should feel familiar:

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

image

This is a fiddler trace of a typical SSO transaction involving ADFS:

Frame 1: I navigate to https://claimsweb.cloudready.ms. It performs a 302 redirect of my client to my ADFS server to authenticate.

Key Takeaway: For this initial redirection to occur, the application needs to know the ADFS login URL.

Frame 2: My client connects to my ADFS server https://sts.cloudready.ms/adfs/ls/?wa=wsignin1.0&wtrealm=https://claimsweb.cloudready.ms&wctx=rm%3d0%26id%3dpassive%26ru%3d%252f&wct=2013-12-09T08%3a05%3a07Z

Key Takeaway: Since ADFS may have multiple relying party applications, it needs a piece of identifying information to know which relying party application to invoke. Consequently, the application must send an application identifier. ADFS must also know whether this is a SAML or WS-Fed application. If the request is signed, ADFS must also have public portion of the application signing certificate but request signing is optional.

Frame 3: If the request is signed and the signature passes, I will authenticate to ADFS. The ADFS server will ensure I’m authorized for this RP application via the issuance authorization configuration on the RP and then process the claims via the Issuance configuration on the RP. The ADFS server will then send the client browser some HTML with a SAML token and a JavaScript that tells my client to POST it over to the original claims-based application.

Key Takeaway: For all of this to happen, you would need issuance authorization rules on the RP (if they apply), claims rules on RP, the public token encryption certificate (if applies), and lastly, ADFS needs to know what URL to have the client POST the token back to on the application side, this is called the Consumer Assertion Endpoint.

Frame 4: My client sends that token back to the original application: https://claimsweb.cloudready.ms. Claimsweb reads the ADFS identifier, verifies the signature on the token, decrypts the token (if applies), reads the claims, and then loads the application

Key Takeaway: For all of this to happen, the application will need the ADFS identifier, the public portion of the token signing certificate, it already has its own token decryption certificate, and then needs to know what claims are in the token.

 

Summary

So here is a breakdown of what is needed. The following table is a summary of all the things needed to build a relying party trust and what things the relying party trust owner will need as well.

Key:

X   Signifies who needs this key piece of information

<–> Signifies who is responsible for providing this information

A Blue column signifies whether this is a required piece of information

chart

Condensed Version

If you want a condensed version of this information, here it is. To create just about any replying party trust, regardless of platform, on-premises, off-premises, SAML, WS-Fed, whatever, you will need the following information from the relying party application owner:

  • Does the application support RP-Initiated Sign-on?
  • The application metadata if they have one. (Optional)
  • Is the application SAML or WS-Fed?
  • Identifier of the application. This can be a URL or URI.
  • A SAML request signing certificate if there is one. (Optional)
  • If they want to authorize that certain users can use this application or not. (Optional)
  • What claims, claim types, and claims format should be sent. (Optional)
  • If token encryption is desired, the public portion of the token encryption certificate. (Optional)
  • The URL/endpoint that the token should be submitted back to.
  • The supported secure hash algorithm, SHA-1 or SHA-256. Most SAML applications are SHA-1 while most WS-Fed applications are SHA-256.
  • Whether the application needs RelayState support. (Optional)

You will need to provide the relying party application owner with the following information:

The biggest problem you’ll run into when setting up your relying party trusts is rarely is there someone that knows exactly what is needed to configure both sides and even if there is, everyone calls these components something different. Consequently, we have created an ADFS Onboarding document that we recommend be used by customers. Not only does it help them document all relying party applications that will be created but also helps drive the conversation of what exactly is need from each party.

Click Here to Download Onboarding Document

Warning: Stop now, if you don’t want any further detail on each of these components. Continue to read on if you have some free time and are interested in understanding each of these. Smile

 

RP-Initiated Sign-on Support

Type: Required

Who Needs to Know This:  The ADFS owners

RP-initiated sign-on is typically a topic we reserve for advanced ADFS discussions but it is something that has to be known when you’re onboarding applications to ADFS. Simply put, RP-Initiated Sign-On is if the user can navigate to the application first to gain access to the application. I know this sounds like a simple concept and the answer should typically be Yes, but why do we need to ask this?

We have to ask because some SaaS application providers might be in a multi-tenant configuration and because of this, if they send all users from many customers to the same application URL, the application now needs to figure out where to redirect them for authentication, Microsoft calls this Home Realm Discovery (HRD). Some SaaS providers don’t know or want to be responsible for redirecting users from many customers to different ADFS environments. Perhaps it’s a legal issue or a technical issue but if you know this, then you’ll have to start thinking about something called IDP-initiated sign-on, which is simply providing your users with special ADFS URL’s so they kick off the SSO transaction with ADFS first, which then logs them into the application.

Another reason is ask this question is because if they don’t support this and if your users bookmark pages within the application, those bookmarks will fail to log them in. Hence the requirement for special ADFS URL’s that can log them in instead. We’ll cover this in another post down the road.

 

Federation Metadata

Type: Optional

Who Needs to Know This: Both parties, if possible.

If you can, use this to configure both sides. ADFS publishes a metadata that can be consumed by the some relying party trust application to configure it with all the parameters that it needs. From my experience, most SSO and SAML applications don’t support importing a metadata though. Nonetheless, you can access your ADFS metadata from https://<sts.domain.com>/federationmetadata/2007-06/federationmetadata.xml. If your partner cannot access this URL for some reason, you can also download the .xml document from your browser and email it to them.

Some SSO applications may also have a metadata that you can import to create the relying party trust in ADFS. If it is available from a URL, you can just type that metadata into the RP creation wizard or import the downloaded .xml document:

image

From my experience though, many application vendors don’t support publishing a metadata. Another thing to note is that ADFS may not support all the options that are present in the metadata. If so, you will either have to strip those elements out of the metadata or manually create the relying party trust.

Key Takeaway: Ask the relying party trust owner if they have a metadata that you can import from a file or URL. Also let the relying party trust owner know that you have a metadata that is available at the above URL or can be emailed to them. These metadata files can configure both sides of the trust and make your life much easier.

 

ADFS Logon URL

Type: Required

Who Needs to Know This: Application Owners

If the application supports RP-initiated sign-on, the application owners will need to know the URL to redirect users to on ADFS so they can authenticate. The application will need the following information:

URL: https://<sts.domain.com>/adfs/ls/

Method: POST or Redirect

 

Application Identifier

Type: Required

Who Needs to Know This: ADFS Owners

After the login request has been sent over to ADFS, being that ADFS may have many configured relying party trusts, it needs to know which ones we’re trying to access. This is achieved by sending the ADFS server an “identifier” in the request. It can be a URL or URI, but both sides have to be configured with the same identifier.

The following are examples of how WS-Fed and SAML application will send their identifier in the logon request:

WS-Fed Sign-On Protocol:

This is probably a little deeper than I need to cover this but I really want you to understand how the relying party application includes this identifier. Many Microsoft applications including SharePoint, O365, or anything based on the Windows Identity Foundation (WIF) may use the WS-Fed Sign-in protocol. WS-Fed application will send a URL parameter called WTRealm indicating their identifier.

For example, I captured this following URL after going to https://claimsweb.cloudready.ms. Since this is a WS-Fed request, we’ll be looking for the WTRealm URL parameter:

https://sts.cloudready.ms/adfs/ls/?wa=wsignin1.0&wtrealm=https://claimsweb.cloudready.ms&wctx=rm%3d0%26id%3dpassive%26ru%3d%252f&wct=2013-12-09T08%3a05%3a07Z

On my ADFS server, you can see that my relying party trust for claimsweb has the same identifier:

image

SAML Sign-On Protocol:

The process for finding the identifier for a SAML application is little different and requires a decoding tool since the SAML request is Base64 encoded.

For example, I captured this URL after going to https://shib.cloudready.ms/Secure.

Copy the SAMLRequest value from the redirected URL:

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

Go to https://idp.ssocircle.com/sso/toolbox/samlDecode.jsp

Paste in the SAML value and ensure that redirect is selected. It will spit out the following SAML Request XML and we can determine the identifier:

<samlp:AuthnRequest Version="2.0" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" IssueInstant="2013-12-09T08:03:17Z" ID="_c9e91bb6135e72c9a8133122f42a3785" Destination="https://sts.cloudready.ms/adfs/ls/" AssertionConsumerServiceURL="https://shib.cloudready.ms/Shibboleth.sso/SAML2/POST" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://shib.cloudready.ms/Shibboleth</saml:Issuer><samlp:NameIDPolicy AllowCreate="1"/></samlp:AuthnRequest>

Once again, on my ADFS configuration, you can see that my SAML relying party trust has the same identifier:

image

Key Takeaway: The identifier is really just a URL or URI value that has to be the same on both sides of the configuration so ADFS knows which RP to invoke for the logon request.

 

Request Signing Certificate

Type: Optional

Who Needs to Know This: The ADFS owners need this.

Rarely do you find that the requests will need to be signed but if so, the application owner will sign it with the private certificate and you’ll need their public certificate to check the signature. If the request do need to be signed, it’s typically always with SAML applications. As you can see here, my WS-Fed application doesn’t have a certificate configured, hence no request signing will be enforced here:

image

By default, the request signing certificate must pass revocation. If you’re having issues and you suspect the request signing certificate isn’t publically trusted, you can run the following command against the certificate, once you copy it to file to check it’s revocation status:

certutil –urlfetch –verify <RequestSigningCert.cer>

 

Issuance Authorization

Type: Optional

Who Needs to Know This: Both parties should discuss who should perform AuthZ.

While I usually recommend that AuthZ occur on the application side, I think it really depends on the nature of the application. Before any claims or tokens are issued back to the client’s browser, the ADFS server will perform authorization of whether they have access to the specific relying party application they are trying to access. This authorization can be based on specific groups you belong or other user claims information pulled from AD, LDS or a SQL database. You can build authorization rules based on the Exists, NotExists, or AND operators so these rules can be very complex:

For example, we could ensure that only CloudReady.ms\HRAdmins are the only group permitted to this this claimsweb.cloudready.ms application:

image

If this is my only authorization rule and I’m not in the HRAdmins group, ADFS will never get around to processing the claims and sending my browser a token because I’ll receive Access Denied right up front:

image

 

Claims Issuance

Type: Required

Who Needs to Know This: The ADFS owners

If I do belong to the HRAdmins, ADFS now moves onto processing the claims that will be returned to my browser in a SAML token. The configuration of the relying party trust in ADFS and the application must be configured with the same claims information although if you send them more claims than the application requires, they’ll probably just ignore them.

image

 

SAML: Claims, Claim Type & Format

Type: Optional

Who Needs to Know This: The ADFS owners

Many SAML applications will want the claims sent with a certain claim type and format. The claim format is an additional piece of metadata that tells the application what type of information is being sent. I only have found this requirement with SAML applications and most require that the claim of email, UPN or SAMAccountName be sent with the NameID claim type and various claim formats.

The first claims rule would get the email attribute from Active Directory:

image

While the second claims rule would transform it into a NameID claims type with a format of unspecified although you can pick from the Outgoing name ID format which format the application desires:

image

 

Token Encryption Certificate

Type: Optional

Who Needs to Know This: The ADFS owners

Next, ADFS needs to know whether the application requires the SAML token be encrypted. If so, the application owner must provide you with the public portion of their token encryption certificate. Most applications don’t require token encryption since the token is protected by SSL and has a digital signature associated with it but if one is required, your relying party trust must have it configured:

image

 

Application Token Endpoints

Type: Required

Who Needs to Know This: ADFS Owners

Now, ADFS returns a SAML token to client’s browser and some JavaScript instructs my browser to post that token back to a URL on the application side. The endpoint is just the URL on the SSO application side that is listening and waiting for a SAML token. When you configure this on the relying party trust in ADFS, you must indicate whether it is WS-Fed or SAML application. Consequently, this is your opportunity to configure the token endpoints and the Sign-In Protocol Type:

image

You can see my claimsweb relying party trust is configured with WS-Fed and SAML endpoints. I configured both just for demonstration purposes as you would normally only have one or the other configured. The binding method for each is typically POST.

image

 

Secure Hash Algorithm

Type: Required

Who Needs to Know This: ADFS Owners

The relying party trust in ADFS must be configured with the correct secure hash algorithm. Most SAML applications will support SHA-1 while most WS-Fed applications will support SHA-256. Go to the properties of the relying party application in ADFS and then advanced tab and pick the correct hash algorithm from the drop-down:

SAML:Typically SHA-1

WS-Fed: Typically SHA-256

image

 

Token Signing Certificate

Type: Required

Who Needs to Know This: Application Owners

One of the first things the application does is check the digital signature of the token not only to ensure who the token came from but also ensure it wasn’t modified in transit. To properly do this, the application must have the public portion of the ADFS server’s token signing certificate. Every application must have a copy of the ADFS server’s token signing certificate. Some applications will accept this certificate in .cer format while others require .pem format. Applications based off of the Windows Identity Foundation (WIF) only need the thumbprint of the certificate pasted into their web.config. To export the token signing certificate from ADFS, open up the certificates container, go to the properties of the token signing certificate and then to the details tab and at the bottom, you see “Copy to File”:

image

Do not export the private key:

image

If they want it in .CER format, select the DER encoded binary X.509. If they want it in .PEM format, select the Base-64 encoded X.509.

image

 

ADFS Identifier

Type: Required

Who Needs to Know This: Application Owners

Next, after the signature passes, the application will check the issuer to ensure it came from the right identity provider so it checks the identifier value in the token.

If I search the token that ADFS sent the application, I will find an issuer attribute and it identifiers the name of the ADFS server that sent the token.

<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" IssueInstant="2013-12-09T08:13:11.633Z" Issuer="http://sts.cloudready.ms/adfs/services/trust" AssertionID="_aacc5dc2-64fb-44c5-bc03-a144faa8efe4" MinorVersion="1" MajorVersion="1">

In this case, the issuer was http://sts.cloudready.ms/adfs/services/trust. The SSO application must have this ADFS identifier in its configuration.You can view your ADFS identifier by left clicking on the Service container at the root of the ADFS console and then right click>Edit Federation Service Properties:

image

image

Mega Takeaway: The lack of https on this ADFS identifier doesn’t matter because it is just a string value that must match on both sides. I know a lot of engineers that couldn’t configure SSO because they accidentally typed https on the application identifier side and missed this minor oversight.

 

RelayState

Type: Optional

Who Needs to Know This: The ADFS owners

RelayState is some application state that needs to be maintained throughout the SSO transaction. You’ll need to ask the application owner whether they will need RelayState support. If so, you’ll need to ensure that all ADFS servers and ADFS Proxy/WAP servers have this enabled:

https://technet.microsoft.com/en-us/library/jj127245(v=ws.10).aspx

All ADFS 2.x servers and ADFS Proxy servers:

  • %systemroot%\inetpub\adfs\ls\web.config

ADFS 2012 R2 Servers:

  • %systemroot%\ADFS\Microsoft.IdentityServer.Servicehost.exe.config

 

ADFS Logout URL

Type: Required

Who needs to know this: Application owners

Officially logging out of the application isn’t necessarily required but for your deployments, it should be. You’ll need to provide the application owners with your logout URL. The logout method is different depending on whether the application is WS-Fed or SAML. If the application is WS-Fed, just provide them with the following URL:

For SAML applications, this gets a little more tricky. SAML application are supposed to logout by sending the user to ADFS with a SAML Logout Request (SLO) like:

This is an sample SLO request and not intended to be used.

https://<sts.domain.com>/adfs/ls/?SAMLRequest=hZJLS8QwFIX3gv%2BhZD9t0ql9hJkBYVQGxvGJCzdySW600CQ1NwX993bqExe6y318h3sOWRDYrpdb%2F%2BiHeI3PA1JMXmznSE6TJRuCkx6oJenAIsmo5M3x%2BVbmKZd98NEr37EfyN8EEGGIrXcs2ayX7GJ3sr042%2BwecqFNI6BuqrKqq8YobiptShBFw1XJOVe1KItCs%2BQOA438ko1yowjRgBtHEVwcW1wUM17NRH3LhRRzyct7lqxHT62DOFFPMfYyyyhSqjo%2F6ICgX1NLGWhDWUcZWx0eJMlib0VO6mH1yfQpvoDtO0yVt5lG60VmMYKGCGn%2F1C%2Byn9S3zG6MYbNObi73j6sButa0GL5v%2BU%2BXJac%2BWIh%2FR7vvtHpmplUZAzhq0UW2%2BgrZNLlSop4XOOU7x0bxxhR1bhTWnM8rKPMjgdWHj%2FezRx%2Fv9a9fsnoD

Key Takeaway: You’ll find many SAML application owners just recommend that using the WS-Fed logout URL you see above. While this is a workaround that typically works, this is NOT the correct way to perform SAML logout.

 

Advanced: SAML & AuthnContextClassRef

Type: Optional

Who Needs to Know This: The application owners needs to know what is supported.

One of my customers had a SAML application that worked while users were in the corporate network but wouldn’t work when they were outside the corporate network going through their ADFS proxy. It took me a while to figure this one out.

When the application redirects the user to ADFS, it can indicate which authentication type they want it to enforce in the request. For example, a SAML application can send a parameter in the SAMLRequest that requires ADFS to perform integrated Windows authentication by sending a AuthnContextClassRef of urn:federation:authentication:windows like:

image

The only problem with this is what if the user is outside the corporate network and is going through their ADFS Proxy/WAP for access to the application? – The ADFS proxy/WAP can’t perform integrated Windows Authentication and can only perform Forms-Based Authentication (FBA). Consequently, the ADFS Proxy was bombing out each time for this application while users were external. We had to configure the SAML application to send two authentication types in the AuthnContextClassRef of the SAML Request – one for integrated Windows authentication and one for username/password authentication separated by semi-colon:

urn:federation:authentication:windows;urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport

Note: This setting was required in the configuration of Cisco Jabber.

David “I write long blogs for some reason and don’t know why, damn, there I go again, ok I’m done” Gregory.

ADFS Onboarding Document.pdf