当组(或子组(如果递归))包含ForeignSecurityPrincipal时,GroupPrincipal.GetMembers失败 [英] GroupPrincipal.GetMembers fails when group (or child group if recursive) contains ForeignSecurityPrincipal

查看:103
本文介绍了当组(或子组(如果递归))包含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提出了支持电话,他们已确认这是一个问题。内部已引发一个错误,但尚未确认是否会修复该错误。

I raised a support call with Microsoft and they have confirmed it as an issue. A bug has been raised internally but it has not been confirmed whether this will be fixed.

Microsoft建议使用以下解决方法代码,但它可以执行

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).aspx
FSP在AD中不是真正的对象,而是驻留在不同的受信任域/林中的对象的占位符(指针)。它也可以是特殊身份之一,这些特殊身份是一堆知名帐户,由于其SID与域SID不同,因此也被归为FSP。
例如,此处记录的匿名身份验证用户,批处理和其他几个帐户:
http://technet.microsoft.com/zh-cn/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.

希望这对某人有帮助。

    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

Thanks, R

这篇关于当组(或子组(如果递归))包含ForeignSecurityPrincipal时,GroupPrincipal.GetMembers失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆