加入会员AD组从受信任域会员、AD

由网友(还记得那年的悲哀)分享简介:我有两个域,在建立信任关系,那我想从C#的Web应用程序来管理。为了做到这一点,我要模仿两种不同的技术用户,但做工不错,所以我不会强调的code部分。 I have two domains, in a trusted relationship, that I'm trying to manage from a C#...

我有两个域,在建立信任关系,那我想从C#的Web应用程序来管理。为了做到这一点,我要模仿两种不同的技术用户,但做工不错,所以我不会强调的code部分。

I have two domains, in a trusted relationship, that I'm trying to manage from a C# web application. To do that, I have to impersonate two different technical users, but that works good, so I will not emphasize that part of the code.

要建立适当的和易于管理的ACL的文件系统,我必须

To build proper and easy to manage ACLs for the file system, I must

在domainA中创建一个组(好!) 找到用户在域B(好!) 将用户添加到组(提交更改失败时,错误消息:在服务器上没有这样一个对象(从HRESULT异常:为0x80072030)

如果我来自同一个域添加用户,在code完美的作品,所以我相信,我只在这里缺少的一小部分信息。我用本文作为参考,看见this问题以及(和一些更多的引用此错误消息),但都没有帮助。

If I'm adding a user from the same domain, the code works perfectly, so I believe I'm only missing a small partial info here. I used this document as a reference and saw this question as well (and a few more citing this error message) but neither of them helped.

code(try-catch块去掉,使其更简单)

Code (try-catch block removed to make it simpler)

// 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;
}

第6行的作品,如果我调试它,或者强制属性写入到的Htt presponse,这是明显存在的。因此,LDAP查询似乎是确定。

Line 6 works, if I debug it or force the properties to be written to HttpResponse, it is clearly there. So the LDAP queries seem to be OK.

另外,如果我注释掉线6并取消7,所以基本上我添加一个用户从同一个域,在整个事情的作品奇迹般地。随着域B,我坚持。任何好的忠告?

Also, if I comment out line 6 and uncomment 7, so basically I add a user from the same domain, the whole thing works miraculously. With domainB, I'm stuck. Any good piece of advice?

推荐答案

随着你的code,我看你得到作为一个参数,它在域A 。然后,你要创建的DirectoryEntry 对象 DOM ,这是越来越模拟,但从来没有得到使用。但是,你想从域B添加对象直接用 LDAP 。该行:

Following your code, I see that you're getting de as a parameter, which is in Domain A. Then you're creating DirectoryEntry object dom, which is getting impersonated, but never getting used. However, you're trying to add an object from Domain B to de directly using LDAP. This line:

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

没有得到模拟

假设你的模拟工作正常,使用 DOM 对象这已经是模拟 DirectorySearcher从找到域B 然后用户加入从域B

Assuming your impersonation works correctly, use dom object which is already impersonated with DirectorySearcher to find the user in Domain B and then add the user object from Domain B to de.

...
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 });
    }
}
...

UDPATE

这个例子会告诉你如何得到用户的 SID 从一个域,搜索组从另一个域,并使用 SID 。

UDPATE

This example will show you how to get user SID from one domain, search group from another domain and add user to group using 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();
              }
           }
        }
     }
 }

请注意,我跳过所有的模拟在上面的code。

Please note that I skipped all the impersonation in the above code.