We might come across these attributes when we build applications that require role-based security. In this article, I am just going to list out what are the differences between memberOf and tokenGroups. Both are Active Directory schema attributes that used to retrieve user’s group membership in different manner. The memberOf attribute holds only user’s direct group membership while as the tokenGroups attribute retrieves direct group membership and nested group memberships.
Memberof Attribute
- This is multi-valued back link attribute (computed attribute) that contains the list of distinguished names for groups.
- This attribute holds only user’s direct group membership and it does not contain the recursive list of nested groups.
- Holds both Security groups and Distribution lists.
- It does not contain the user’s primary group. (we can retrieve this group by using user’s primaryGroupID).
- As this is a back link attribute (computed attribute), the group object always holds the member attribute (forward link). The memberOf attribute is a calculated from the group member object. The group membership is always managed from the group object side of the relationship and the back link is updated by the system automatically.
- Dot NET Application developers can read both ways, from SearchResult and DirectoryEnrty (using System.DirectoryServices).
TokenGroups Attribute
- The tokenGroups attribute is multi-valued constructed attribute that holds the list of security identifiers (SID) for groups.
- This attribute holds both direct group membership and the recursive list of nested groups.
- Holds only Security groups and it does not include Distribution lists.
- Includes the user’s primary group.
- As this is constructed attribute, its valued will be calculated only when we read the attribute.
- Dot NET Application developers can read only through DirectoryEnrty (using System.DirectoryServices) and you need to use RefreshCache in user’s DirectoryEntry to get attribute value.
See the below C# sample code to retrieve nested group memberships.
//----using System.DirectoryServices; private static List<string> GetNestedGroupMembershipsByTokenGroup(string userDN) { List<string> nestedGroups=new List<string>(); DirectoryEntry userEnrty = new DirectoryEntry("LDAP://" + userDN); // Use RefreshCach to get the constructed attribute tokenGroups. userEnrty.RefreshCache(new string[] { "tokenGroups" }); foreach (byte[] sid in userEnrty.Properties["tokenGroups"]) { string groupSID = new SecurityIdentifier(sid, 0).ToString(); DirectoryEntry grpuEnrty = new DirectoryEntry("LDAP://<SID=" + groupSID + ">"); nestedGroups.Add(grpuEnrty.Properties["samAccountName"][0].ToString()); } return nestedGroups; }
Advertisement
For PowerShell use this to enumerate TokenGroups:
$user = [ADSI]"LDAP://CN=User,OU=MyOU,DC=domain,DC=com"
$user.psbase.refreshCache(@("TokenGroups"))
$secirc = new-object System.Security.Principal.IdentityReferenceCollection
foreach($sidByte in $user.TokenGroups)
{
$secirc.Add((new-object System.Security.Principal.SecurityIdentifier $sidByte,0))
}
$secirc.Translate([System.Security.Principal.NTAccount]) | Sort-Object
Thanks to whoever posted the original version of this 🙂
“TokenGroups” calculated property is really powerfull for groups having the GROUP_TYPE_SECURITY_ENABLED flag in their groupType attribute, and I use it with System.DirectoryServices (I already wrote the same “sample” code as yours, in my actual and past projects).
Question for groups that don’t have this flag : is there a calculated property (i.e. like “TokenGroups”) for them ? Or is recursive memberOf searching (by algorithm or OID) the only way to achieve this ?
With my apologies for my poor English.