Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GroupPrincipal.GetMembers和跨域成员错误_C#_Active Directory - Fatal编程技术网

C# GroupPrincipal.GetMembers和跨域成员错误

C# GroupPrincipal.GetMembers和跨域成员错误,c#,active-directory,C#,Active Directory,我有两个域,A和B。域A有组GroupA,其中包含来自域B的用户。 我的代码: 对于域B,它工作正常。 如何修复它?检查它在不强制转换到UserPrincipal时是否有不同的行为,例如: var changedUsersFromGroup = principalSearchResult.ToArray(); 据我所知,这可能是一些问题。同样,使用GetMembers(true)返回的不包含组对象的主体集合,只返回叶节点,因此可能根本不需要强制转换。接下来,检查这样的搜索将返回多少结果。如果您

我有两个域,A和B。域A有组GroupA,其中包含来自域B的用户。
我的代码:

对于域B,它工作正常。

如何修复它?

检查它在不强制转换到UserPrincipal时是否有不同的行为,例如:

var changedUsersFromGroup = principalSearchResult.ToArray();

据我所知,这可能是一些问题。同样,使用GetMembers(true)返回的不包含组对象的主体集合,只返回叶节点,因此可能根本不需要强制转换。接下来,检查这样的搜索将返回多少结果。如果您的广告有许多用户/嵌套组,最好不要使用GetMembers(true)来确保它在小用户组上工作。

您似乎正在定义域a的
PrincipalContext
(因此您可以获取组),但由于组内的用户是在域B中定义的,因此上下文无法访问它们(因为它是一个域和一个上下文)

您可能需要为域B定义第二个“PricipalContext”,并对其运行查询,并使用域a组中用户的SID列表筛选对象(您需要获取SID列表,而不会导致底层代码尝试解析它们)


希望有帮助!

不幸的是,我目前无法测试它,但也许你可以试试这个

var contextB = new PrincipalContext(ContextType.Domain, DomainName_B, User_B, Password_B)
[..]
    var changedUsersFromGroup =
                    principalSearchResult
                    .Where(member => member is UserPrincipal)
                    .Where(member => IsModifiedUser(member, usnChanged))
                    .Select(principal => Principal.FindByIdentity(contextB, principal.SamAccountName))
                    .Cast<UserPrincipal>()
                    .Select(adsUser => new AdsUser(adsUser)).Cast<IAdsUser>()
                    .ToArray();
var contextB=new PrincipalContext(ContextType.Domain、DomainName、User、Password)
[..]
var ChangedUserFromGroup=
主搜索结果
.Where(member=>member是UserPrincipal)
.其中(成员=>IsModifiedUser(成员,USN变更))
.Select(principal=>principal.FindByIdentity(contextB,principal.SamAccountName))
.Cast()
.Select(adsUser=>newadsuser(adsUser)).Cast()
.ToArray();
当然,如果所有成员都在域B中,这可能会起作用。如果他们混合在不同的域中,您可能需要在这之前对其进行过滤并在域中进行迭代。
或者,您可以使用域帐户运行应用程序?然后不要传递user/pass,并授予此帐户所需的访问权限以避免出现错误。

说明:域上下文将为您检索到的主体切换(如果您注释掉新的AdsUser/IAdsUser Cast部分,您可以在调试模式下查看此内容)。这似乎是导致异常的原因。虽然这正是我无法测试的部分,但我认为创建AdsUser会创建一个新的ldap绑定到目标域。这与“原始”失败凭据。AdsUser是ActiveDS还是第三方的一部分?
如果传递凭据使用基本身份验证,我没有找到任何提示,但我认为应该是这样。使用应用程序凭据使用协商和“处理此问题”给新的AdsUser(…)应该解决这个问题。

< p>问题发现并报告给MS作为bug。目前不可能用.NET进行(但是它通过原生C++ API通过查询< /p> 工作,至少在.NET 4.7中,可以手动管理枚举器来处理它。这已经被测试过,并且已经成功地通过了错误。

static System.Guid[] GetGroupMemberGuids(System.DirectoryServices.AccountManagement.GroupPrincipal group)
{
    System.Collections.Generic.List<System.Guid> result = new List<Guid>();
    if (group == null) return null;
    System.DirectoryServices.AccountManagement.PrincipalCollection px = group.Members;
    System.Collections.IEnumerator en = px.GetEnumerator();
    bool hasMore = true;
    int consecFaults = 0;
    while (hasMore && consecFaults < 10)
    {
        System.DirectoryServices.AccountManagement.Principal csr = null;
        try
        {
            hasMore = en.MoveNext();
            if (!hasMore) break;
            csr = (System.DirectoryServices.AccountManagement.Principal)en.Current;
            consecFaults = 0;
        }
        catch (System.DirectoryServices.AccountManagement.PrincipalOperationException e)
        {
            Console.Error.WriteLine("    Unable to enumerate a member due to the following error: {0}", e.Message);
            consecFaults++;
            csr = null;
        }
        if (csr is System.DirectoryServices.AccountManagement.UserPrincipal)
            result.Add(csr.Guid.Value);
    }
    if (consecFaults >= 10) throw new InvalidOperationException("Too many consecutive errors on retrieval.");
    return result.ToArray();
}
静态系统.Guid[]GetGroupMemberGuids(System.DirectoryServices.AccountManagement.GroupPrincipal组)
{
System.Collections.Generic.List结果=新列表();
if(group==null)返回null;
System.DirectoryServices.AccountManagement.PrincipalCollection px=组成员;
System.Collections.IEnumerator en=px.GetEnumerator();
布尔·哈斯莫尔=真;
int=0;
while(hasMore&&10)
{
System.DirectoryServices.AccountManagement.Principal csr=null;
尝试
{
hasMore=en.MoveNext();
如果(!hasMore)中断;
csr=(System.DirectoryServices.AccountManagement.Principal)en.Current;
故障数=0;
}
捕获(System.DirectoryServices.AccountManagement.PrincipalOperation异常)
{
Console.Error.WriteLine(“由于以下错误而无法枚举成员:{0}”,e.Message);
错误++;
csr=null;
}
if(csr是System.DirectoryServices.AccountManagement.UserPrincipal)
结果.Add(csr.Guid.Value);
}
如果(连续错误>=10)抛出新的InvalidOperationException(“检索时连续错误过多”);
返回result.ToArray();
}

如果您有时间在GAC中反编译相关程序集,您可能会看到出现此异常的条件以及此错误消息。我个人的猜测是,当时与DC的连接存在问题,因此该消息具有误导性。除了第二次尝试之外,解决此问题非常困难。
var contextB = new PrincipalContext(ContextType.Domain, DomainName_B, User_B, Password_B)
[..]
    var changedUsersFromGroup =
                    principalSearchResult
                    .Where(member => member is UserPrincipal)
                    .Where(member => IsModifiedUser(member, usnChanged))
                    .Select(principal => Principal.FindByIdentity(contextB, principal.SamAccountName))
                    .Cast<UserPrincipal>()
                    .Select(adsUser => new AdsUser(adsUser)).Cast<IAdsUser>()
                    .ToArray();
static System.Guid[] GetGroupMemberGuids(System.DirectoryServices.AccountManagement.GroupPrincipal group)
{
    System.Collections.Generic.List<System.Guid> result = new List<Guid>();
    if (group == null) return null;
    System.DirectoryServices.AccountManagement.PrincipalCollection px = group.Members;
    System.Collections.IEnumerator en = px.GetEnumerator();
    bool hasMore = true;
    int consecFaults = 0;
    while (hasMore && consecFaults < 10)
    {
        System.DirectoryServices.AccountManagement.Principal csr = null;
        try
        {
            hasMore = en.MoveNext();
            if (!hasMore) break;
            csr = (System.DirectoryServices.AccountManagement.Principal)en.Current;
            consecFaults = 0;
        }
        catch (System.DirectoryServices.AccountManagement.PrincipalOperationException e)
        {
            Console.Error.WriteLine("    Unable to enumerate a member due to the following error: {0}", e.Message);
            consecFaults++;
            csr = null;
        }
        if (csr is System.DirectoryServices.AccountManagement.UserPrincipal)
            result.Add(csr.Guid.Value);
    }
    if (consecFaults >= 10) throw new InvalidOperationException("Too many consecutive errors on retrieval.");
    return result.ToArray();
}