【问题标题】:How to avoid groupPrincipal.Members.Add throwing a NoMatchingPrincipalException如何避免 groupPrincipal.Members.Add 抛出 NoMatchingPrincipalException
【发布时间】:2013-02-11 14:07:35
【问题描述】:

我得到了一个 Active Directory 域,我在其中创建了某个新创建的 OU 下的组对象,如下所示,例如SubOuB 下的组。 GlobalGroups 下的全局组已经存在。

+MainOu
   +--SubOuA
     +--GroupA_A
     +--GroupA_B
     +--GroupA_C
  +--SubOuB
     +--GroupB_A
     ...
+GlobalGroups
  +--GlobalGroupA
  +--GlobalGroupB
  ...

现在我想将新创建的 OU 下新添加的组作为成员添加到全局组之一,例如将 GroupA_A 添加为 GlobalGroupB 的成员:

using( PrincipalContext principalContext =
    new PrincipalContext( ContextType.Domain, Environment.UserDomainName ) )
{
    GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(
        principalContext, "GlobalGroupB" );
    if( groupPrincipal != null )
    {
        // Target group found.
        groupPrincipal.Members.Add( principalContext, IdentityType.Name, "GroupA_A" );
        // The next line throws a NoMatchingPrincipalException.
        groupPrincipal.Save();
    }
}

当我查看 AD 结构和对象时,我可以看到这两个对象。 ADSI 编辑器显示两个“名称”都是正确的。当我在创建新的 OU 和组对象后在测试应用程序中手动运行代码时,将组作为成员添加到全局组中也可以正常工作。我使用的所有代码都在具有相同结构的 AD 的暂存环境中工作,所以我不确定为什么它在生产环境中会出现问题。

有什么想法吗?我已经看到 DirectoryEntry 对象有一个 RefreshCache 方法强制重新加载特定对象的属性值,但我认为这在这里没有帮助。我的问题是时间问题吗?我可以强制“重新加载”现有对象,以便找到新创建的组并将其添加到全局组中吗?

更新

这肯定是 AD 同步的问题 - 当我不断检查新创建的组对象是否存在(例如,使用 Thread.Sleep(1000) 循环)时,我的代码按预期工作。缺点是我不知道我必须等待多长时间(在我的环境中测试在 6 到 15 秒之间变化),我也认为这是一种非常肮脏的方法。不幸的是,我找不到有关如何“刷新”AD 对象或“刷新”缓存的任何信息。

更新 2

当我连接到特定的域控制器时,第一个查询很慢(3000+ 毫秒),随后的查询更快,并且都需要大约相同的时间返回。我仍然不知道如何避免在预期对象确实可用(作为查询结果)之前定期查询 AD。

【问题讨论】:

    标签: c# active-directory principal


    【解决方案1】:

    据我所知,解决我的问题的唯一方法如下:

    • 按照我的问题中的建议执行并定期查询“您的”域控制器,直到期望对象可用或达到可配置的超时时间
    • 通过Domain.DomainControllers检索所有可用的域控制器并查询它们,直到找到您的对象

    我不太喜欢这两种方式,但我找不到任何其他选择。请随时提出更好的替代方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多