Hi all. This is Sean again and it’s ADFS blog time! Today I’m going to touch on Security Assertion Markup Language (SAML) tokens, and an issue we’ve run into when federating
with Tivoli Federated Identity Manager (TFIM)
. I’ll discuss what a SAML token is, why it’s important, and what happens when TFIM tries to validate one from ADFS.
As you may know, the Active Directory Federation Service (ADFS) uses SAML tokens to represent claims. These claims about a user are made by the Federation Service Account (FS-A) server. The claims located in the SAML token are what allow the Federation Service Resource (FS-R) server to determine what claims to grant the user in the resource’s domain. Generally, the transaction goes something like this:
The client requests a SAML token from the FS-A server. The client authenticates to the server using Windows credentials.
The FS-A creates the SAML token that contains claims for the user (group membership, UPN, etc) and issues the token to the client. This token is signed with the token signing certificate and also has a proof key encrypted for the FS-R server.
The client receives a copy of the proof key as well. The client will present the SAML token to the FS-R and sign the message with the proof key.
The signatures allow the FS-R to verify that the SAML token was actually issued by the FS-A to the specific client presenting it.
After this happens, the SAML token is verified, the claims are extracted, and the rest of the ADFS process continues, right?
Well, almost. In addition to validating the SAML token using the public key of the certificate that the FS-A used to sign it, the FS-R also looks at time conditions specified in the token. To view the SAML token, you will need to enable the verbose debug level on the Federation Service Properties page. This can be done on either the FS-A or the FS-R. The log file will be located in the log files directory that you specify.
In the SAML token you will see a condition block close to the top that looks like this:
Note the “NotBefore” and “NotOnOrAfter” conditions that are in bold. These mean exactly that. If the SAML token is presented to the FS-R BEFORE the NotBefore time, or ON or AFTER the NotOnOrAfter time, then the SAML token will fail validation. Generally you’ll get an error message on the FS-R to the effect of “Unable to Validate Signature on SAML Token.”
It’s important to note that the time used to check against these values is the local time on the FS-R (whether it’s an ADFS FS-R or another solution like TFIM). The issue comes when the FS-A and the FS-R clocks are not in sync. Let’s explore this with an example.
Let’s say we have a client from Adatum.com trying to access a resource in Treyresearch.net. The client will hit the website, get redirected to the Treyresearch.net federation server, perform the client realm discover, and get redirected to the Adatum.com federation server. At this point we’ll go through the process outlined above for obtaining a SAML token. Now, the Adatum resource server is going to set the NotBefore time to the time the SAML token was issued based on its local time. So, if it has a time of 11:31AM when the SAML token is issued, that’s what the NotBefore time will be set to. When the client gets redirected back to the Treyresearch federation server, the NotBefore time will be compared to its local time. If the time on the Treyresearch federation server is set to something earlier than 11:31AM then the token validation will fail.
Apparently someone in the ADFS development group understood that this could be a common issue. To help mitigate the issue, in a federated environment with ADFS running on the resource side the FS-R will allow for a token that is sent five minutes “in the future.” This eliminates the need for absolutely strict time consistency between two completely separate organizations.
On the other hand, TFIM strictly enforces the NotBefore setting in the token. If the local time is before the NotBefore setting then the SAML token will fail validation. So, if ADFS is setup as the account partner, and TFIM is setup as the resource partner, the ADFS federation server’s time cannot be ahead of the TFIM federation server’s time. Let’s consider this with another example.
Suppose an ADFS FS-A issued a SAML token with a NotBefore time of 11:31. The client then gets redirected to a TFIM FS-R whose local time is 11:29. When the TFIM server goes to validate the SAML token, it will fail because the NotBefore time hasn’t been reached.
To help alleviate this issue Microsoft released hotfix
that makes the allowed time difference between the ADFS server and the TFIM server configurable. Once the hotfix is installed on the FS-A, the web.config file on the FS-A can include the <TokenIssuanceNotBeforeSkewInMinutes> tag inside of the <FederationServerConfiguration> tag. If you wanted to set a 5 minute skew, the web.config file would contain this:
So, what’s the moral of this story? If you’re running ADFS on the account side of a federation and TFIM is hosting the resource side, make sure you’ve got time synced on both servers or download the hotfix to configure a little wiggle room. Otherwise you will be “Unable to Validate Signature on SAML Token” as well.