【问题标题】:How can I query if a user of one domain is a member of a group in another AD domain?如何查询一个域的用户是否是另一个 AD 域中的组的成员?
【发布时间】:2011-07-06 20:09:27
【问题描述】:

我有一系列应用程序都使用我创建的相同 C#、.Net 2.0 代码来检查用户是否是 Active Directory 组的成员。

直到最近,当我将来自另一个受信任的 AD 域的用户添加到我的一个 AD 组时,我的代码才遇到任何问题。我的问题是如何检查用户是否是 Active Directory 组的成员,无论其域如何。换句话说,他们可能与我的组在同一个域中,也可能不在同一个域中。下面是我编写并使用多年的代码,用于搜索用户是否在 Active Directory 组中。我不确定我从哪里改编了这段代码,但我假设它来自 MSDN 文章。此外,该解决方案必须适用于 .Net 2.0 框架。我在.Net 3.5 中找到了很多可能解决这个问题的答案。不幸的是,这不适用于我的场景。

//This method takes a user name and the name of an AD Group (role).  
//Current implementations of this method do not contain the user's domain 
//with userName, because it comes from the Environment.UserName property.
private static bool IsInRole(string userName, string role)
{
    try
    {
        role = role.ToLowerInvariant();
        DirectorySearcher ds = new DirectorySearcher(new DirectoryEntry(null));
        ds.Filter = "samaccountname=" + userName;
        SearchResult sr = ds.FindOne();
        DirectoryEntry de = sr.GetDirectoryEntry();
        PropertyValueCollection dir = de.Properties["memberOf"];
        for (int i = 0; i < dir.Count; ++i)
        {
            string s = dir[i].ToString().Substring(3);
            s = s.Substring(0, s.IndexOf(',')).ToLowerInvariant();
            if (s == role)
                return true;
        }
        throw new Exception();
    }
    catch
    {
        return false;
    }
}

【问题讨论】:

    标签: c# .net active-directory .net-2.0 ldap


    【解决方案1】:

    这不是您正在等待的答案,但我希望它可以提供帮助。

    第一 ;您假设您的代码在域中工作,但我看不到它在哪里照顾用户'主要组'。如果您选择一个组作为“用户主体组”,则该组不再是成员属性的一部分。

    第二 ;据我了解,查看用户是否存在于组中的一种方法(我希望不是唯一的,但我仍在寻找)是“recusively”查找用户'group' 对象的 'member' 属性中的 DN。因此,在您的情况下,您可能会询问您的域和另一个域。您可以对每个域进行一次搜索。以下是使用控制的“递归单次搜索”示例:

    /* Connection to Active Directory
     */
    string sFromWhere = "LDAP://WIN-COMPUTER:389/";
    DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "dom\\user", "password");
    
    /* To find all the groups that "user1" is a member of :
     * Set the base to the groups container DN; for example root DN (dc=dom,dc=fr) 
     * Set the scope to subtree
     * Use the following filter :
     * (member:1.2.840.113556.1.4.1941:=cn=user1,cn=users,DC=x)
     */
    DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
    dsLookFor.Filter = "(member:1.2.840.113556.1.4.1941:=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)";
    dsLookFor.SearchScope = SearchScope.Subtree;
    dsLookFor.PropertiesToLoad.Add("cn");
    
    SearchResultCollection srcGroups = dsLookFor.FindAll();
    

    备注:例如,您可以使用更准确的过滤器来排除通讯组。


    已编辑(回答 cmets 问题):

    首先:需要凭据吗?如果请求是从属于域或批准域的计算机完成的,我会拒绝。

    第二个和第三个:是的,Microsoft 在AD Search Filter Syntax 中记录了过滤器。我编写这个过滤器的方式是从样本中扣除。

    【讨论】:

    • 我不想问一个愚蠢的问题,但我有两个。首先,此解决方案是否要求用户输入密码?我在 DirectoryEntry 对象的实例化中看到了“密码”条目。如果可能的话,我想避免这种情况。其次,在您的过滤器字符串中,我看到多个“cn=”和“dc=”语句。那些参考的是什么。更好的是,是否有文档引用了所有这些参数的含义?感谢您的帮助。
    • 抱歉,还有一个问题,'member:1.2.840.113556.1.4.1941:' 值是静态值还是我应该从其他位置查询的值?那是什么?
    • 好的,是的,有一个文档。我为此编辑了我的回复。
    • JPBlanc:我已尝试实现您的代码,但无法正常工作。我没有收到任何错误,它似乎可以正常工作——只是 dsLookFor.FindAll() 操作没有返回任何组。我尝试将域附加到用户,但没有帮助。有什么想法吗?
    • 您是否注意连接到定义组的好域?
    猜你喜欢
    • 2019-11-02
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多