ADSI Indirect Group Membership

2019-09-05 22:07发布

问题:

I am trying to create a method that accepts a list of Active Directory security groups and returns a boolean response for whether or not the user is a member (either direct or indirect). I am using Adaxes (which basically extends ADSI with some of their own functionality). They have an object (IAdmGroup) that returns an array of byte[] for all members (direct and indirect) for a group. I want to avoid using that method if I can because some of the groups have very large groups under them (10,000+ users) and I don't want to impact performance if I can help it.

Here is an example of my problem: Group 1 has Group 2 as a member. User 1 is a member of Group 2. If I pass my method User 1 and Group 1 I should get "true". Group 1 also has group 3 in it. Group 3 has 10,000 members and I would hate to have to pull all 10,000+ members of a that group into a collection and search through the collection to see if User 1 is in it.

I am using C#, .Net4.0, and WCF.

Here's what I have so far (I know it's not much)

public Dictionary<string, bool> CheckGroupMembership(List<string> groups, string guid)
{

    var resp = new Dictionary<string, bool>();
    foreach (string group in groups)
    {
        var user = getIADsUser("Adaxes://<GUID=" + guid + ">"); //gets the IADsUser object
        var adGroup = GetGroup(group); //Gets IADsGroup

    }
}

回答1:

You can use System.DirectoryServices.AccountManagement and WindowsPrincipal.

PrincipalContext context = new PrincipalContext(ContextType.Domain, "DomainName");
UserPrincipal user = UserPrincipal.FindByIdentity(context, guid);

WindowsPrincipal wpuser = new WindowsPrincipal(new WindowsIdentity(user.UserPrincipalName));
bool blIsInRole = wpuser.IsInRole("TheGroupName");
if (blIsInRole)
  Console.WriteLine("IsInRole : Belongs too");
else
  Console.WriteLine("IsInRole : Don't Belongs too");


回答2:

Instead of getting all members of all groups, you need to get the groups a user is a member of:

public Dictionary<string, bool> CheckGroupMembership(List<string> groups, string guid)
{
    // Get GUIDs of groups
    IADsUser user = getIADsUser("Adaxes://<GUID=" + guid + ">"); //gets the IADsUser object
    Object[] parentGroupGuidsArray = (Object[])user.GetEx("adm-MemberOfGuid");
    HashSet<Guid> parentGroupGuids = new HashSet<Guid>();
    foreach (Byte[] guidAsBytes in parentGroupGuidsArray)
    {
        parentGroupGuids.Add(new Guid(guidAsBytes));
    }

    // Add groups to result dictionary
    var resp = new Dictionary<string, bool>(groups.Count, StringComparer.OrdinalIgnoreCase);
    foreach (String group in groups)
    {
        IADsGroup adGroup = GetGroup(group); //Gets IADsGroup
        Guid groupGuid = new Guid((Byte[])adGroup.Get("objectGuid"));
        resp.Add(group, parentGroupGuids.Contains(groupGuid));
    }

    return resp;
}