我正在尝试使用以下代码获取用户的所有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;
}
}
}
此代码正确查找用户主体,但在使用PrincipalOperationException调用GetGroups时失败:未知错误(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
Another report with this problem
任何线索?
答案 0 :(得分:31)
添加Environment.UserDomainName作为PrincipalContext的名称参数帮助:
using (var context = new PrincipalContext(ContextType.Domain, Environment.UserDomainName))
我仍然不知道为什么PrincipalContext(ContextType.Domain)仅用于查找UserPrincipal而不是用户的组。 COM错误消息“未知错误”不是很有帮助,只有ContextType的PrincipalContext构造函数重载在MSDN上几乎没有记录。正如Harvey Kwok指出的那样,它就像.NET框架的问题一样。
答案 1 :(得分:0)
如问题注释中所述,调用GetGroups
时可能发生此特定错误的另一个原因是a documented bug in .NET and .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;
}