AD FS 2.0 and AD FS 1.x Interoperability
Hi, it’s Adam Conkle again. I am excited about our recent release of AD FS 2.0 on May 5. I wanted to post a blog about AD FS 2.0 and AD FS 1.x interoperability as soon as possible since I think it will be a common scenario for our customers.
AD FS 2.0 and AD FS 1.x interoperability was a priority for this release, and full functionality of AD FS 1.x security token servers (STS) and the Claims-aware Web Agent is supported in AD FS 2.0.
Note: AD FS 2.0 does not support the AD FS 1.x Windows Token Web Agent
In order to federate between the two versions of AD FS there are some requirements that we need to manually address.
AD FS 1.x includes three claim types:
- Identity – claims to uniquely identify the user
- Group – claims to show security group membership
- Custom – any other attribute you need to extract and send (i.e. – Given name, surname, office, phone, etc.)
Below, I will describe methods to send claims from AD FS 2.0 which satisfy the AD FS 1.x claim requirements.
We will be extracting several claims from an Attribute Store, and, before we begin, we need to understand where the extractions should take place. You can extract from the Attribute Store either on the Claims Provider (CP) Trust or on the Relying Party (RP) Trust. Both will work; the difference is this:
When you extract using the CP Trust rules, the claims are injected into the policy processing pipeline early in the process. Then, on the RP Trust, we execute the Issuance Authorization Rules and can make RP authorization decisions based on claims that we already have in the pipeline.
When you extract using the RP Trust rules, the claims are injected into the pipeline later in the process, and any Issuance Authorization Rules you have configured for the RP Trust will not apply to claims which are issued here since the authorization rules have already executed.
Name Identifier (Name ID) claim in the SAML subject
In AD FS 1.x, we require at least one Identity Claim (UPN, Email, or Common Name). The Identity Claim is sent as the subject of the SAML 1.1 assertion as a claim called Name Identifier (Name ID). Name Identifier also has a format property which equals the URI of the primary Identity Claim sent. For example, if userPrincipalName (UPN) is sent as the primary Identity Claim, then the Name Identifier claim is specified with the format of UPN with the claim value equal to the UPN of the authenticating user.
Here is a snippet of AD FS 1.x SAML assertion showing the Name Identifier claim:
When we utilize AD FS 2.0 there is no concept of Identity Claims, and we also do not automatically send a Name ID claim. This needs to be manually configured so that AD FS 2.0 will send the Name ID claim to the AD FS 1.x server in a format that the AD FS 1.x server is expecting. Simply issuing a UPN claim from AD FS 2.0 to AD FS 1.x does not achieve the requirement, and a Claim Rule is needed.
Let’s go to the AD FS 2.0 STS, and let’s also assume that AD FS 2.0 is the identity provider (IdP) for this federation scenario. We will configure an Acceptance Transform Rule for the Active Directory CP Trust which extracts userPrincipalName from Active Directory as the UPN claim type (URI). Creating this rule on the CP Trust will place the UPN claim into the pipeline prior to any RP Trust rules firing.
When you create this rule, use the Send LDAP Attributes as Claims template in the rule editor.
Figure 1 – Selecting a claim rule template to extract from AD
Figure 2 and Figure 3 show a rule named Extract UPN from AD which has been added to the claim rules for the Active Directory CP Trust.
Figure 2 – Configuring the Claim Rule to extract UPN from AD
Figure 3 – New rule has been created to extract UPN from AD
Now that we have a UPN claim in the pipeline, the next step is to transform this claim into the format that AD FS 1.x requires: Name ID. We perform the transformation with an Issuance Transform Rule on the AD FS 1.x RP Trust.
To create a transformation rule, use the Transform an Incoming Claim template in the rule editor
Figure 4 – Selecting a claim rule template to transform a claim
Configure the rule to transform from the Incoming claim type: UPN to the Outgoing claim type: Name ID. Once you select Name ID as the outgoing claim type, the Outgoing name ID format drop-down box becomes available so that we can select the UPN format for Name ID. We want to pass the value of the user’s UPN to the new claim, so select Pass through all claim values.
Figure 5 – Configuring the transformation rule for Name ID
When a user authenticates to the AD FS 2.0 STS, the UPN will be extracted from AD during execution of the AD CP Trust rules and injected into the pipeline. Next, the processing rules are executed for the AD FS 1.x RP Trust, and UPN will be transformed to Name ID with the UPN format. The value of the user’s UPN is maintained for the outgoing claim to the RP (AD FS 1.x).
AD FS 1.x Identity Claims
Now that we have the Name ID claim handled, we still need to send the appropriate Identity Claim(s) to AD FS 1.x. For that purpose, AD FS 2.0 includes Claim Descriptions for AD FS 1.x UPN and AD FS 1.x E-Mail Address.
Figure 6 – AD FS 1.x Claim Descriptions shown in the Claim Descriptions node of AD FS 2.0
We simply need to extract them from our Attribute Store (AD, in my case), and send them to the AD FS 1.x RP.
Figure 7 shows how to configure the claim rule to extract UPN and E-Mail as AD FS 1.x UPN and AD FS 1.x E-Mail Address. I have chosen to create this rule on the CP Trust.
Figure 7 – Configuring a rule to extract AD FS 1.x claims from AD
In Figure 8, I have selected the Pass Through or Filter an Incoming Claim template so I can pass the AD FS 1.x claim types to the AD FS 1.x RP. This rule is created on the RP Trust so that the claims accepted from the AD CP Trust can be passed to the RP.
Figure 8 – Selecting the claim rule template to pass a claim through to the RP
Finally, in Figure 9, I have configured the rule to Pass through all claim values for the Incoming claim type: AD FS 1.x UPN. You will need to create another set of extraction and pass through rules to handle the AD FS 1.x E-Mail Address or Common Name claim types if you wish to send them.
Figure 9 - Configuring a claim rule to pass through the value of the AD FS 1.x UPN claim type
AD FS 1.x Group Claims
Next, you may need to send Group claims to AD FS 1.x. AD FS 2.0 comes with a built-in Claim Description named Group which has the URI that AD FS 1.x expects for Group Claims. This can be seen on the Claim Descriptions node in the AD FS 2.0 MMC console.
Figure 10 – Group Claim Description on the Claim Descriptions node of AD FS 2.0
AD FS 2.0 also has a Claim Rule template named Send Group Membership as a Claimwhich allows you to select a security group, and send a claim based on membership of that group. I have chosen to create this rule on the RP Trust.
Figure 11 – Selecting the claim rule template to send a claim based on group membership
Now, all we need is the AD FS 1.x Incoming Group Claim Mapping name the AD FS 1.x administrator is expecting on the resource federation server. For our example, let’s call it SharePointUsersMapping. Our rule looks like this:
Figure 12 – Configuring a claim rule to send a Group claim based on group membership
Since I created my rule on the RP Trust this time, there is no need to create a pass-through rule in order for the claim to be sent to the RP.
AD FS 1.x Custom Claims
We’re on the home stretch now! Finally, we may need to send additional claims to AD FS 1.x which are neither Identity Claims nor Group Claims; they are AD FS 1.x Custom Claims. As an example, I have extended my AD schema to include a user attribute named costCenter. I want to send the users’ cost center as a claim when they authenticate to a resource hosted by my AD FS 1.x partner.
I need to create a new Claim Description to handle this on the AD FS 2.0 STS, but I need to do a bit of background work before I create the new Claim Description. If I take a look at a SAML assertion from AD FS 1.x which contains a Custom Claim, it looks like this:
The way the SAML assertion is constructed here is as follows:
1. The full URI of the claim type is passed in
2. Everything after the last “/” in the URI is stripped off of the URI and is used as the AttributeName property
3. Everything before the last “/” in the URI is used as the AttributeNamespace property
Consider the following full URI:
https://schemas.xmlsoap.org/claims/FirstNameMapping
Now, run that through the steps above:
1. https://schemas.xmlsoap.org/claims/FirstNameMapping is passed in
2. FirstNameMapping is stripped off of the URI and is used as the AttributeName property
3. https://schemas.xmlsoap.org/claims is used as the AttributeNamespace property
I’m ready to create my Claim Description for costCenter, which is accomplished on the Claim Descriptions node of the AD FS 2.0 MMC console:
Figure 13 – Configuring a new Claim Description for Cost Center
The AD FS 1.x administrator will need to create an Incoming Custom Claim Mapping named costCenter so that the incoming claim is mapped.
The last thing we need to do on the AD FS 2.0 federation server is create a rule using the Send LDAP Attributes as Claims template to extract the costCenter attribute from AD and send it to AD FS 1.x as our new claim type. I have chosen to do this on the RP Trust which, again, negates the need for an additional pass-through rule to the RP.
Figure 14 – Configuring a rule template to extract costCenter from AD and send as Cost Center
We’re done! This blog post covers AD FS 2.0 as the Claims Provider (Identity Provider) and AD FS 1.x as the Relying Party (Resource Provider) because it is AD FS 1.x which has the special claims requirements. You can certainly configure AD FS 1.x as the Claims Provider and AD FS 2.0 as the Relying Party, but that deployment should be a bit more straight-forward since AD FS 2.0 simply needs to be configured to accept the incoming claims from AD FS 1.x. Thanks for reading, and please let me know if there are any questions or points needing clarification.
Thanks!
Adam “So He Claims” Conkle
Comments
Anonymous
October 06, 2010
Adam, great article. I think it's also worth mentioning that if you're federating with a partner that has ADFS 1.0 running on Server 2003, you'll need to ask them to install the following hotfix: support.microsoft.com/.../948963 An alternative that I don't really recommend is to turn off token encryption using the following two PowerShell commands: Add-PSSnapin Microsoft.Adfs.Powershell Set-ADFSRelyingPartyTrust –TargetName "Your RP Display Name Here" –EncryptClaims $FalseAnonymous
October 06, 2010
Hi Frank, Thanks for the reply. You make a great point regarding SHA2 support for Windows Server 2003. We actually have several KBs which will add this support for you, and I typically use: support.microsoft.com/.../968730. The SHA2 support will be required if you have AutoCertificateRollover enabled for AD FS 2.0, but is not necessarily required if your CA-issued token-signing certificate does not use SHA2. Regarding your point about token encryption, AD FS 1.x actually doesn't support token encryption even though the WS-Federation spec allows it. When AD FS 2.0 is the IP-STS and AD FS 1.x is the RP-STS, you must not encrypt the claims sent to AD FS 1.x since it has no mechanism for decryption. We are still safe because, keep in mind, that our transport is protected via SSL. Thanks for the feedback! AdamAnonymous
October 07, 2010
Adam, Thanks for the follow-up! In our case, we've obtained a SHA-1 certificate to ensure interoperability with ADFS 1.x partners, but good to know that KB968730 would allow Server 2003 to accept a SHA-2 token-signing or the "AutoCertificateRollover" self-signed (?) cert. Also, did not realize that ADFS 1.x doesn't support token encryption. So in that case, ignore my original comment, everyone! Instead, if you need to work with an ADFS 1.x partner, be sure to disable token encryption by running the following two PowerShell commands on your ADFS 2.0 environment: Add-PSSnapin Microsoft.Adfs.Powershell Set-ADFSRelyingPartyTrust –TargetName "Your RP Display Name Here" –EncryptClaims $False Let me know if I'm off-base at all, Adam. Thanks again, FrankAnonymous
October 07, 2010
Frank, You're on track. In most cases, the PowerShell command will not be needed because AD FS 1.x does not publish an encryption certificate in any Federation Metadata, and customers will be adding the Relying Party Trust for AD FS 1.x by entering the partner data manually. When you enter the data manually, token encryption will already be disabled since you are not specifying a certificate on the Encryption tab of the RP Trust. Token encryption in AD FS 2.0 works like an AND gate: For token encryption to occur, you must have the EncryptClaims property == TRUE and you must also have a token encryption certificate specified. That said, if EncryptClaims == TRUE and there is no encryption certificate specified, the claims will not be encrypted, thus there is no need to run the PowerShell command. Thanks, AdamAnonymous
October 07, 2010
Adam, OK, that makes sense. Generally speaking, for ADFS 2.0 trust relationships, if an encryption certificate is specified on the relying party trust, it's supposed to be the exported certificate (public key only) of the partner organization's ADFS token-signing cert... correct? In our case that's how we had it setup (though it sounds like this is unnecessary with ADFS 1.x). Thanks, FrankAnonymous
October 07, 2010
Adam, Two other quick questions:
- We discovered that our ADFS 1.x partner was attempting to perform a CRL check on our token-signing certificate. Is CRL checking of the token-signing certificate specific to ADFS 1.x, or would an ADFS 2.0 partner also perform CRL validation? In reading online documentation, we saw references to recommendations that the token-signing certificate be issued by an internal CA, but unless internal CRLs are published externally and made highly-available, I think I would recommend that token-signing certificates be obtained from a publically-trusted certificate authority.
- In trying to federate with an ADFS 1.x partner, we found that we could not leave our "Federation Service Identifier" to be of the default format: servername.domainname.com/.../trust and instead we had to change it to: URN:servername.domainname.com (or really anything in this URN format seemed to work). Is it another ADFS 1.x interoperability "gotcha" that we had to change our federation service identifier from the default http format to the URN format? Thanks, Frank
- Anonymous
December 01, 2010
Frank, Did you ever find an answer to your last question about the federation identifier format? I had the same question except in my case we are federating ADFS 2.0 with Opensso using WS Fed instead of saml.