Question

I have an ASP.NET Framework 4.5 app with the following function to check if user is a member of an AD group:

public static bool IsUserGroupMember(string userName, string groupName)
{
    string domain = "ad.our.org";
    string defaultOU = "OU=Our_Department,DC=ad,DC=our,DC=org";
    PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domain, defaultOU, ContextOptions.SimpleBind);
    UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, userName);
    GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(principalContext, groupName);

    return oGroupPrincipal.Members.Contains(oUserPrincipal);
}

However, this only works when the user is directly a member of the group and not a member of another group nested within this group.

Hope to get help fixing this code to check membership recursively through every nested group within the group. I looked at answers to similar issues in StackOverflow but can't figure out how to best modify my function to make it work.

Thanks.

Was it helpful?

Solution

This is what you want:

public static bool IsUserGroupMember(string userName, string groupName)
{
    using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
    using (UserPrincipal user = UserPrincipal.FindByIdentity(context, userName))
    using (PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups())
    {
        return groups.OfType<GroupPrincipal>().Any(g => g.Name.Equals(groupName, StringComparison.OrdinalIgnoreCase));
    }
}

OTHER TIPS

If you're using a System.DirectoryServices.Protocols library, u can use this specific filter for get ALL nested groups, where the user belongs to and is NOT a direct member only:

    var filterForNestedGroups = $"(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={user}))";
    var searchRequestForGroups = new SearchRequest(
        monitoredOptions.ActiveDirectoryDomainControllers, filterForNestedGroups, SearchScope.Subtree);

    var searchResponseForGroups = (SearchResponse)connection.SendRequest(searchRequestForGroups);
    var groupList = new List<string>();
    var groups = searchResponseForGroups.Entries;
    var groupsCount = searchResponseForGroups.Entries.Count;

    for (var index = 0; index < groupsCount; index++)
    {
        var group = groups[index].Attributes["cn"]?[0].ToString();
        if (string.IsNullOrEmpty(group) == false)
            groupList.Add(group);
    }

Please note that user variable MUST be a DistinguishedName value!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top