当组(或子组,如果递归)包含 ForeignSecurityPrincipal 时 GroupPrincipal.Get

GroupPrincipal.GetMembers fails when group (or child group if recursive) contains ForeignSecurityPrincipal(当组(或子组,如果递归)包含 ForeignSecurityPrincipal 时 GroupPrincipal.GetMembers 失败)
本文介绍了当组(或子组,如果递归)包含 ForeignSecurityPrincipal 时 GroupPrincipal.GetMembers 失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

对于遇到相同问题的任何人来说,这与其说是一个问题,不如说是一个信息.

出现以下错误:

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).aspx And the container is documented here : http://msdn.microsoft.com/en-us/library/cc200915(v=PROT.10).aspx A 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 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Finding Active Directory users from 2 OU(从 2 个 OU 中查找 Active Directory 用户)
How to set a binary attribute when using a AccountManagement Extension Class?(使用 AccountManagement 扩展类时如何设置二进制属性?)
Getting last Logon Time on Computers in Active Directory(在 Active Directory 中的计算机上获取上次登录时间)
Active Directory - Roles of a user(Active Directory - 用户的角色)
How to connect to Active Directory via LDAPS in C#?(如何在 C# 中通过 LDAPS 连接到 Active Directory?)
Why is DirectorySearcher so slow when compared to PrincipalSearcher?(与 PrincipalSearcher 相比,为什么 DirectorySearcher 如此缓慢?)