UserPrincipal.GetGroups fails with unknown error

旧街凉风 提交于 2019-12-12 09:29:25

问题


I am trying to get all Active Directory groups for a user, with the following code:

    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;
            }
        }
    }

This code correctly finds the user principal, but fails when GetGroups is called with a PrincipalOperationException: Unknown error (0x80005000).

Root exception:

   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]

Inner exception (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

Another report with this problem.

Any clues?


回答1:


Adding Environment.UserDomainName as the name argument to the PrincipalContext helped:

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

I still don't know why PrincipalContext(ContextType.Domain) only works for finding the UserPrincipal and not the groups of the user. The COM error message "unknown error" is not very helpful and the PrincipalContext constructor overload with only the ContextType is virtually undocumented at MSDN. It smells like an issue with the .NET framework as pointed out by Harvey Kwok.




回答2:


As mentioned in the question comments, another reason this particular error can happen when calling GetGroups is due to a documented bug in .NET and .NET Core. It happens when attempting to get groups for user principals that have a slash ('/') in their AD Distinguished Name.

The workaround, at least until the bug is fixed, is to write your own GetGroups method. Here is a working example that returns just the group names (also includes distribution lists):

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;
}


来源:https://stackoverflow.com/questions/4518472/userprincipal-getgroups-fails-with-unknown-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!