从受信任的域添加成员到AD组

msh*_*thn 10 c# active-directory active-directory-group

我有两个域,在一个受信任的关系中,我正在尝试从C#Web应用程序进行管理.要做到这一点,我必须冒充两个不同的技术用户,但这样做很好,所以我不会强调代码的那一部分.

为了构建适当且易于管理的文件系统ACL,我必须这样做

  • 在domainA中创建一个组(OK!)
  • 在domainB中找到一个用户(好的!)
  • (提交更改,错误消息时失败:将用户添加到组There is no such object on the server. (Exception from HRESULT: 0x80072030))

如果我正在添加来自同一域的用户,则代码可以正常运行,所以我相信我在这里只缺少一些小的部分信息.我使用这个文档作为参考,也看到了这个问题(还有一些引用了这个错误信息),但它们都没有帮助.

代码(删除了try-catch块以使其更简单)

// de is a DirectoryEntry object of the AD group, received by the method as a parameter
// first impersonation to search in domainB
// works all right
if (impersonator.impersonateUser("techUser1", "domainB", "pass")) {
    DirectoryEntry dom = new DirectoryEntry("LDAP://domainB.company.com/OU=MyOU,DC=domainB,DC=company,DC=com", "techUser1", "pass");
    de.Invoke("Add", new object[] { "LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" });
    // de.Invoke("Add", new object[] { "LDAP://domainA.company.com/CN=anotherUserFromDomainA,OU=AnotherOU,DC=domainB,DC=company,DC=com" });
    impersonator.undoImpersonation();
}

// second impersonation because the group (de) is in domainA
// and techUser2 has account operator privileges there
if (impersonator.impersonateUser("techUser2", "domainA", "pass"))
{
    de.CommitChanges();
    impersonator.undoImpersonation();
    return true;
}
else
{
    // second impersonation was unsuccessful, so return an empty object
    return false;
}
Run Code Online (Sandbox Code Playgroud)

第6行工作,如果我调试它或强制将属性写入HttpResponse,它显然在那里.所以LDAP查询似乎没问题.

另外,如果我注释掉第6行并取消注释7,那么基本上我从同一个域添加一个用户,整个过程奇迹般地工作.有了domainB,我就被困住了.有什么好建议吗?

smr*_*mr5 6

按照你的代码,我看到你得到的de是一个参数,它是在Domain A.然后你正在创建DirectoryEntry对象dom,它正在获取impersonated,但从未被使用过.但是,你想从添加对象Domain B,以de直接使用LDAP.这一行:

de.Invoke("Add", new object[{"LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" }); 
Run Code Online (Sandbox Code Playgroud)

没有得到impersonated.

假设你的impersonation正确工作,使用dom对象,它是已impersonatedDirectorySearcher找到用户Domain B,然后从添加用户对象Domain Bde.

...
using (DirectoryEntry dom = new DirectoryEntry("LDAP://domainB.company.com/OU=MyOU,DC=domainB,DC=company,DC=com", "techUser1", "pass"))
{
    using (DirectorySearcher searcher = new DirectorySearcher(dom))
    {
        searcher.Filter = "(&(objectClass=user)(CN=theUserIWantToAdd))";
        SearchResult result = searcher.FindOne();
        de.Invoke("Add", new object[] { result.Path });
    }
}
...
Run Code Online (Sandbox Code Playgroud)

UDPATE

此示例将向您展示如何SID从一个域获取用户,从另一个域搜索组以及如何使用用户添加用户SID.

//GET THE USER FROM DOMAIN B
using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domainContext, UPN))
{
    if (userPrincipal != null)
    {
       //FIND THE GROUP IN DOMAIN A
       using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, groupName))
       {
          if (groupPrincipal != null)
          {
             //CHECK TO MAKE SURE USER IS NOT IN THAT GROUP
             if (!userPrincipal.IsMemberOf(groupPrincipal))
             {
                string userSid = string.Format("<SID={0}>", userPrincipal.SID.ToString());
                DirectoryEntry groupDirectoryEntry = (DirectoryEntry)groupPrincipal.GetUnderlyingObject();
                groupDirectoryEntry.Properties["member"].Add(userSid);
                groupDirectoryEntry.CommitChanges();
              }
           }
        }
     }
 }
Run Code Online (Sandbox Code Playgroud)

请注意,我跳过impersonation了上面代码中的所有内容.