Active directory: получить группы, в которых пользователь является членом - PullRequest
3 голосов
/ 05 сентября 2011

Я бы хотел найти список групп, в которых пользователь является участником.Я пробовал несколько решений из http://www.codeproject.com/KB/system/everythingInAD.aspx, но безрезультатно.

Этот код дает мне "true", значит LDAP работает:

public static bool Exists(string objectPath)
{
    bool found = false;
    if (DirectoryEntry.Exists("LDAP://" + objectPath))
        found = true;
    return found;
}

Спасибо,

Обновление 1:

public ArrayList Groups(string userDn, bool recursive)
{
    ArrayList groupMemberships = new ArrayList();
    return AttributeValuesMultiString("memberOf", "LDAP-Server",
        groupMemberships, recursive);
}

public ArrayList AttributeValuesMultiString(string attributeName,
string objectDn, ArrayList valuesCollection, bool recursive)
{
    DirectoryEntry ent = new DirectoryEntry(objectDn);
    PropertyValueCollection ValueCollection = ent.Properties[attributeName];
    IEnumerator en = ValueCollection.GetEnumerator();

    while (en.MoveNext())
    {
        if (en.Current != null)
        {
            if (!valuesCollection.Contains(en.Current.ToString()))
            {
                valuesCollection.Add(en.Current.ToString());
                if (recursive)
                {
                    AttributeValuesMultiString(attributeName, "LDAP://" +
                    en.Current.ToString(), valuesCollection, true);
                }
            }
        }
    }
    ent.Close();
    ent.Dispose();
    return valuesCollection;
}

У меня есть исключение:

PropertyValueCollection ValueCollection = ent.Properties[attributeName];

"COMException is nothandled"

Ответы [ 4 ]

8 голосов
/ 05 сентября 2011

В .NET 4 вы можете сделать это очень легко с новым классом UserPrincipal следующим образом:

using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
    UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "your_login");
    foreach (var group in user.GetGroups())
    {
        Console.WriteLine(group.Name);
    }
}

Вы должны добавить ссылку на System.DirectoryServices.AccountManagementввести необходимые типы.

1 голос
/ 06 сентября 2011

Я нашел решение для stackoverflow.Формат строки подключения выглядит следующим образом:

LDAP://domain.subdomain.com:389/DC=domain,DC=subdomain,DC=com

Код:

  public IList<string> GetGroupsByUser(string ldapConnectionString, string username)
        {
            IList<string> groupList = new List<string>();

            var identity = WindowsIdentity.GetCurrent().User;
            var allDomains = Forest.GetCurrentForest().Domains.Cast<Domain>();

            var allSearcher = allDomains.Select(domain =>
            {
                var searcher = new DirectorySearcher(new DirectoryEntry(ldapConnectionString));

                // Apply some filter to focus on only some specfic objects
                searcher.Filter = String.Format("(&(&(objectCategory=person)(objectClass=user)(name=*{0}*)))", username);
                return searcher;
            });

            var directoryEntriesFound = allSearcher
                .SelectMany(searcher => searcher.FindAll()
                    .Cast<SearchResult>()
                    .Select(result => result.GetDirectoryEntry()));

            var memberOf = directoryEntriesFound.Select(entry =>
            {
                using (entry)
                {
                    return new
                    {
                        Name = entry.Name,
                        GroupName = ((object[])entry.Properties["MemberOf"].Value).Select(obj => obj.ToString())
                    };
                }
            });

            foreach (var item in memberOf)
                foreach (var groupName in item.GroupName)
                    groupList.Add(groupName);

            return groupList;
        }
0 голосов
/ 19 июля 2013

Используйте этот код вместо вашей версии. Это даст вам список. Разница между этим и оригинальным заключается в использовании DirectorySearcher.

    public ArrayList AttributeValuesMultiString(string attributeName,
         string objectDn, ArrayList valuesCollection, bool recursive)
    {
        using (DirectoryEntry ent = new DirectoryEntry(objectDn))
        {
            using (DirectorySearcher searcher = new DirectorySearcher(ent))
            {
                searcher.PropertiesToLoad.Add(attributeName);
                var result = searcher.FindOne();
                ResultPropertyValueCollection ValueCollection = result.Properties[attributeName];
                IEnumerator en = ValueCollection.GetEnumerator();

                while (en.MoveNext())
                {
                    if (en.Current != null)
                    {
                        if (!valuesCollection.Contains(en.Current.ToString()))
                        {
                            valuesCollection.Add(en.Current.ToString());
                            if (recursive)
                            {
                                AttributeValuesMultiString(attributeName, "LDAP://" +
                                en.Current.ToString(), valuesCollection, true);
                            }
                        }
                    }
                }
            }
        }
        return valuesCollection;
    }
0 голосов
/ 26 октября 2012

Вы уверены, что приведенный выше скрипт корректен и работает правильно?Я не думаю, что это будет учитывать членство во вложенных группах, поэтому я боюсь, что вы, возможно, не получаете полный набор всех групп, к которым принадлежит пользователь.

Видите ли, пользователь может быть участникомгруппы X, и группа X, в свою очередь, может быть членом группы Y, так что в результате пользователь также станет членом группы Y.

Я думаю, что приведенный выше сценарий может быть не в состоянии расширить и перечислить вложенные членства в группах.

Я бы посоветовал также рассмотреть этот аспект, если вы хотите получить полный наборчленство, к которому принадлежит пользователь.

Я полагаю, что существуют некоторые другие вопросы, касающиеся определения членства в группе.Здесь есть хорошая дискуссия, если вы хотите узнать больше:

http://www.activedirsec.org/t39703252/why-is-it-so-hard-to-enumerate-nested-group-memberships-in-a/

Я бы хотел, чтобы это было намного проще, но, похоже, это не так: - (

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...