Ошибка UserPrincipal.GetGroups с неизвестной ошибкой

Я пытаюсь получить все группы Active Directory для пользователя со следующим кодом:

    private static IEnumerable<string> GetGroupNames(string userName)
    {
        using (var context = new PrincipalContext(ContextType.Domain))
        {
            using (var userPrincipal = UserPrincipal.FindByIdentity(context, userName))
            {
                var groupSearch = userPrincipal.GetGroups(context);
                var result = new List<string>();
                foreach (var principal in groupSearch)
                {
                    Log.LogDebug("User {0} is member of group {0}", userPrincipal.DisplayName, principal.DisplayName);
                    result.Add(principal.SamAccountName);
                }
                return result;
            }
        }
    }

Этот код правильно находит участника-пользователя, но завершается ошибкой при вызове GetGroups с ошибкой PrincipalOperationException: Unknown (0x80005000).

Корневое исключение:

   at System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOf(Principal foreignPrincipal, StoreCtx foreignContext)
   at System.DirectoryServices.AccountManagement.Principal.GetGroupsHelper(PrincipalContext contextToQuery)
   at System.DirectoryServices.AccountManagement.Principal.GetGroups(PrincipalContext contextToQuery)
   at [line of the GetGroup call]

Внутреннее исключение (COMException):

   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.PropertyValueCollection.PopulateList()
   at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
   at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
   at System.DirectoryServices.AccountManagement.ADUtils.RetriveWkDn(DirectoryEntry deBase, String defaultNamingContext, String serverN

Еще один отчет с этой проблемой.

Любые подсказки?


person Holstebroe    schedule 23.12.2010    source источник
comment
Это происходит у всех пользователей? Или это происходит только у конкретного пользователя? Я знаю, что в библиотеке .NET есть ошибка, которая выдает это COMException, когда DN пользователя содержит /. У меня также есть решение этой проблемы, если вы подтвердите, что это происходит только для пользователя с DN, содержащим / only   -  person Harvey Kwok    schedule 24.12.2010
comment
У меня проблема, которую вы описываете. У меня проблема с получением групп, когда DN пользователя содержит /. Можете ли вы сказать мне, какое исправление вы используете, пожалуйста?   -  person Lamelas84    schedule 31.01.2017
comment
У меня такая же проблема для пользователей, содержащих / в DN. Что было исправлено?   -  person bahramzy    schedule 20.04.2017
comment
Я не получил ответа от Харви Квока. До сих пор с этим проблемы.   -  person Lamelas84    schedule 15.05.2017


Ответы (2)


Добавление Environment.UserDomainName в качестве аргумента имени в PrincipalContext помогло:

using (var context = new PrincipalContext(ContextType.Domain, Environment.UserDomainName))

Я до сих пор не знаю, почему PrincipalContext(ContextType.Domain) работает только для поиска UserPrincipal, а не групп пользователя. Сообщение об ошибке COM «неизвестная ошибка» не очень полезно, а перегрузка конструктора PrincipalContext только с ContextType практически не документирована в MSDN. Это похоже на проблему с платформой .NET, как указал Харви Квок.

person Holstebroe    schedule 27.12.2010
comment
Был точно такой же результат от вызова UserPrincipal.IsMemberOf( GroupPrincipal ), когда текущий пользователь не является участником. Действительно, использование конструктора PrincipalContext( ContextType, string ) решает внутреннюю проблему! - person Astrogator; 21.06.2016
comment
Тоже была именно эта проблема. Он будет случайным образом выбрасывать DirectoryServicesCOMException с HRESULT 0x80072030 или конвертировать из uint в int это .ErrorCode == -2147016656. Случалось только в рабочей среде, но не на виртуальных машинах разработки с медленным подключением к AD. Использование PrincipalContext(ContextType, string) .ctor, кажется, наконец решило проблему. - person Brian Reiter; 05.01.2017

Как упоминалось в комментариях к вопросу, еще одна причина, по которой эта конкретная ошибка может возникнуть при вызове GetGroups, связана с задокументированная ошибка в .NET и .NET Core. Это происходит при попытке получить группы для субъектов-пользователей, у которых есть косая черта ('/') в отличительном имени AD.

Обходной путь, по крайней мере, пока ошибка не будет исправлена, состоит в том, чтобы написать собственный метод GetGroups. Вот рабочий пример, который возвращает только имена групп (включая списки рассылки):

public static List<string> GetGroups(UserPrincipal user)
{
    List<string> groupNames = new List<string>();

    using (DirectoryEntry directoryEntryUser = (DirectoryEntry)user.GetUnderlyingObject())
    {
        object[] groups = GetAdPropertyValueObjectArray(directoryEntryUser, "memberOf");
        const int prefixLength = 3;
        const string prefix = "CN=";  // CN = Common Name

        if (groups != null)
        {
            foreach (string group in groups)
            {
                if (group.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                {
                    int commaIndex = group.IndexOf(",", prefixLength);
                    string groupName;

                    if (commaIndex >= 0)
                        groupName = group.Substring(prefixLength, commaIndex - prefixLength);
                    else
                        groupName = group.Substring(prefixLength);

                    if (groupName.Length > 0)
                        groupNames.Add(groupName);
                }
            }
        }
    }

    return groupNames;
}

private static object[] GetAdPropertyValueObjectArray(DirectoryEntry userAccount, string adPropertyKey)
{
    object[] result = null;
    PropertyValueCollection property = userAccount.Properties[adPropertyKey];

    if (property != null)
    {
        object propertyValue = property.Value;

        if (propertyValue != null)
        {
            if (propertyValue is string)
            {
                result = new object[1];
                result[0] = propertyValue;
            }
            else
            {
                result = (object[])propertyValue;
            }
        }
    }

    return result;
}
person Tawab Wakil    schedule 21.02.2019