问题描述
对于遇到相同问题的任何人来说,这与其说是一个问题,不如说是一个信息.
出现以下错误:
System.DirectoryServices.AccountManagement.PrincipalOperationException: An error (87) occurred while enumerating the groups. The group's SID could not be resolved.
at System.DirectoryServices.AccountManagement.SidList.TranslateSids(String target, IntPtr[] pSids)
at System.DirectoryServices.AccountManagement.SidList.ctor(List`1 sidListByteFormat, String target, NetCred credentials)
at System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.TranslateForeignMembers()
当运行以下代码并且组或子组包含 ForeignSecurityPrincipal 时:
When the following code is run and a group or child group contains a ForeignSecurityPrincipal:
private static void GetUsersFromGroup()
{
var groupDistinguishedName = "CN=IIS_IUSRS,CN=Builtin,DC=Domain,DC=com";
//NB: Exception thrown during iteration of members rather than call to GetMembers.
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "Domain", "Username", "Password"))
{
using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, groupDistinguishedName))
{
using (var searchResults = groupPrincipal.GetMembers(true))//Occurs when false also.
{
foreach (UserPrincipal item in searchResults.OfType())
{
Console.WriteLine("Found user: {0}", item.SamAccountName)
}
}
}
}
}
我向 Microsoft 拨打了支持电话,他们已确认这是一个问题.内部提出了一个错误,但尚未确认是否会修复.
Microsoft 建议使用以下解决方法代码,但由于重复调用 UserPrincipal.FindByIdentity,它在具有大量用户的组中表现不佳.
Microsoft suggested the following workaround code but it performs poorly on groups with a large number of users because of the repeated calls to UserPrincipal.FindByIdentity.
class Program
{
//"CN=IIS_IUSRS,CN=Builtin,DC=dev-sp-sandbox,DC=local"; //TODO MODIFY THIS LINE ACCORDING TO YOUR DC CONFIGURATION
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.WriteLine("Usage: ListGroupMembers "group's DistinguishedName"");
Console.WriteLine("Example: ListGroupMembers "CN=IIS_IUSRS,CN=Builtin,DC=MyDomain,DC=local"");
return;
}
string groupDistinguishedName = args[0];
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "dev-sp-dc", "Administrator", "Corp123!");
List<UserPrincipal> users = new List<UserPrincipal>();
listGroupMembers(groupDistinguishedName, ctx, users);
foreach (UserPrincipal u in users)
{
Console.WriteLine(u.DistinguishedName);
}
}
//Recursively list the group's members which are not Foreign Security Principals
private static void listGroupMembers(string groupDistinguishedName, PrincipalContext ctx, List<UserPrincipal> users)
{
DirectoryEntry group = new DirectoryEntry("LDAP://" + groupDistinguishedName);
foreach (string dn in group.Properties["member"])
{
DirectoryEntry gpMemberEntry = new DirectoryEntry("LDAP://" + dn);
System.DirectoryServices.PropertyCollection userProps = gpMemberEntry.Properties;
object[] objCls = (userProps["objectClass"].Value) as object[];
if (objCls.Contains("group"))
listGroupMembers(userProps["distinguishedName"].Value as string, ctx, users);
if (!objCls.Contains("foreignSecurityPrincipal"))
{
UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, dn);
if(u!=null) // u==null for any other types except users
users.Add(u);
}
}
}
}
可以修改上面的代码以查找导致组问题的外国安全主体.
The above code could be modified to find foreign security principals causing problems in groups.
Microsoft 提供了有关外国安全主体的以下信息:
这是 AD 中的一类对象,它代表来自外部源(因此是另一个林/域或下面的特殊"帐户之一)的安全主体.该类记录在此处:http://msdn.microsoft.com/en-us/library/cc221858(v=PROT.10).aspx容器记录在此处:http://msdn.microsoft.com/en-us/library/cc200915(v=PROT.10).aspxFSP 不是 AD 中的真实对象,而是指向位于不同的受信任域/林中的对象的占位符(指针).它也可以是特殊身份"之一,即一堆知名帐户,这些帐户也被归类为 FSP,因为它们的 SID 与域 SID 不同.例如这里记录的匿名、经过身份验证的用户、批处理和其他几个帐户:http://technet.microsoft.com/en-us/library/cc779144(v=WS.10).aspx
This is a class of objects in AD which represents a security principal from an external source (so another forest/domain or one of the "special" accounts below).The class is documented here: http://msdn.microsoft.com/en-us/library/cc221858(v=PROT.10).aspxAnd the container is documented here : http://msdn.microsoft.com/en-us/library/cc200915(v=PROT.10).aspxA FSP is not a real object in AD, but rather a placeholder (pointer) to an object which lives in a different, trusted domain/forest. It can also be one of the "special identities" which are a bunch of well-known accounts who are also classed as FSP’s because their SID’s are different to the domain SID.For example the anonymous, Authenticated User, batch and several other accounts as documented here:http://technet.microsoft.com/en-us/library/cc779144(v=WS.10).aspx
推荐答案
当然这是一个旧线程,但可能对某人有所帮助.我使用下面的代码块来解决问题.Principal 类公开了一个名为 StructuralObjectClass 的属性,它告诉您该主体的 AD 类是什么.我用它来决定对象是否是用户.GetMembers(true) 递归搜索相关 groupPrincipal 中的所有嵌套成员.
Sure this is an old thread, but might help someone. I used the below code block the solve the problem. the Principal class exposes a property called StructuralObjectClass which tells you what is the AD Class of that principal. I used this to decide whether the object is a user. The GetMembers(true) recursively searches all nested-members in the groupPrincipal in question.
希望这对某人有所帮助.
Hope this helps someone.
List<UserPrincipal> members = new List<UserPrincipal>();
foreach (var principal in groupPrincipal.GetMembers(true))
{
var type = principal.StructuralObjectClass;
if (type.Contains("user"))
members.Add((UserPrincipal)principal);
}
谢谢,R
这篇关于当组(或子组,如果递归)包含 ForeignSecurityPrincipal 时 GroupPrincipal.GetMembers 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!