ADFS: Claim rule to issue recursive group membership of a user

In the context of Active Directory Federation Services, the Relying Party Trust configuration implies Issuance Transform Rules, in which miscellaneous info is issued from a user to the application, most of the time the usual SAMAccountName, UPN, Name/Surname, Email Adresses etc.

We’ll consider here the case of a very specific request, but not that uncommon.

User X is a member of an AD Group called “Team_IT“, and this group is a member, among others, of groups “ADMGRP_MyApp” and “ADMGRP_AD“.   We want to issue this recursive membership (i.e. to ADMGRP’s) and, cherry on top, filter the issued group list because Team_IT group is a member of dozens of other groups and we only want the ones beginning with ADMGRP.

There is a direct way to send Group Membership as Claim but it’s kinda crappy. If I understood it well, it only allows you to check ONE group membership, and issue a custom value in the claim type of your choice.  e.g. User X is a member of group Teams_IT, then issue “HelloWorld” in claim type “Name ID”:

No recursive check, no multiple group check. Well you can make one rule per -hardcoded- group; hello flexibility! …

So we are left with custom rules, and we must dive into the fantastic world of ADFS Rule language.  I haven’t understood it all, but know these rules already:

1. The claim type is *whatever you want*.  All drop-down menu entries giving you a claim type, translate this into a line of “rule language” with a link to a non-existent parameter definition.


This link http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname doesn’t actually exist (well, OK, not a 404 because the site itself exists but hey..). You could really give any reference there. But of course when using the claims, you have to give that precise reference.

2. If you use a custom LDAP query, it must be in the form

QUERY = “<QUERY_FILTER>;<ATTRIBUTES>;<DOMAIN_NAME>\<USERNAME>”

where the query filter is not mandatory (default value is current samaccountname); the attributes are those returned and the username is the one used to read the AD (pretty much any authenticated user can).

I quickly found how to return the attribute “memberOf”, but as you may well know this attribute only contains the direct group membership.

There is also a mysterious filter called LDAP_MATCHING_RULE_IN_CHAIN but which only works on a DN (DistinguishedName) object, which is not a value often used in our ADFS context.

So in short we’ll have to create 3 rules to achieve what we want.

In your ADFS rule add wizard : choose “Send Claims as Custom Rule” in the dropdown menu, and be sure to give them this order (rules are processed chronologically):

1. Store the username as distinguishedName (DN)

We store the SAMAccountName into a custom claim type that I named “nameDN” (I totally made up the link from the common “name” type).  Note the query like explained above, which has an empty first parameter (thus the default SAMAccountName, that we want), takes its attribute distinguishedName, and then uses the same Samaccountname again to access AD.

2. Store all group membership recursively, using the syntax with the DN

This is tricky. the chain of numbers is the LDAP_MATCHING_RULE_IN_CHAIN mentioned above. We use 2 parameters also, one still being the SAMAccountname and the other being the custom type DN that we made on the previous rule.
The claims/group is also made up, from the one I found in the example for the next  rule.

3. Issue the filtered list of group following our needs

Using the made up Group type claim, and filtering its name to begin with ADMGRP.

There, both ADMGRP_* groups are correctly issued!

Rule syntax is a merge from MSFT Pierre Audonnet (merci !) and various users on Technet (thanks!)

All sources:

https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-rule-to-send-group-membership-as-a-claim
https://social.technet.microsoft.com/wiki/contents/articles/8008.ad-fs-2-0-selectively-send-group-membership-s-as-a-claim.aspx
https://social.technet.microsoft.com/Forums/ie/en-US/f238d2b0-a1d7-48e8-8a60-542e7ccfa2e8/recursive-retrieval-of-all-ad-group-memberships-of-a-user?forum=ITCG
https://blogs.msdn.microsoft.com/pinch-perfect/2015/09/14/querying-attributes-from-active-directory-using-adfs-with-a-3rd-party-identity-provider/
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/ff608234(v=ws.10)#code-snippet-5
https://social.technet.microsoft.com/Forums/lync/en-US/ca566e15-4b3b-4830-ae65-e25d83251c07/adfs-claim-to-flatten-groups-and-return-full-dn?forum=winserverDS