Reputation: 571
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.
Upvotes: 6
Views: 8643
Reputation: 79
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!
Upvotes: 1
Reputation: 4678
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));
}
}
Upvotes: 13