检索包含子组的组的成员

时间:2019-11-09 15:15:03

标签: c# ldap

我创建了一个dot.net表单,该表单使用c#代码检索用户从下拉列表中选择的Active Directory组的成员,然后在网页上显示成员列表(用户就是我想要的)。

这对于不包含子组的组很好用。当Active Directory组包含用户和子组时,我会收到一条错误消息。

我只希望用户从下拉列表中选择的组的用户。我不要来自任何分组的用户。

我已经在互联网上进行了大量搜索并测试了各种代码建议。

public List<string> GetAllUsersFromGroup(string domain, 
  string group)
{
    List<string> retVal = new List<string>();
    DirectoryEntry entry = new DirectoryEntry(domain);
    DirectorySearcher searcher = new DirectorySearcher("
     (&(objectCategory=Group)(cn=" + group + "))");

    searcher.SearchRoot = entry;
    searcher.SearchScope = SearchScope.Subtree;
    SearchResult result = searcher.FindOne();

    var x = 0;
    var txtCN = ""; 
    var txtDispName = ""; 
    var firstItem = 0; // Display Name
    var secondItem = 1; // CN 
    var arraryResultsSize = result.Properties["member"].Count;
    string[] deResultsArray = new string[arraryResultsSize];

    foreach (string member in result.Properties["member"])
    {
        DirectoryEntry de = new DirectoryEntry(String.Concat(domain, 
        "/", member.ToString()));

        if (de.Properties["objectClass"].Contains("user") && 
        de.Properties["cn"].Count > 0)
        {
            deResultsArray[x] = de.Properties["displayName"]
            [0].ToString() + "~" + de.Properties["cn"]
            [0].ToString();
        }
        x = x + 1;
    }

    if (deResultsArray[0] != null) {
        string[] sortSeperatedItems = sortLDAPUsers(deResultsArray);

        for (var i = 0; i < sortSeperatedItems.Length/2; i++) {
            txtDispName = "<tr><td>" + sortSeperatedItems[firstItem] 
            + "</td>";
            txtCN = "<td>" + sortSeperatedItems[secondItem] + "</td>
            </tr>";
            retVal.Add(txtDispName);
            retVal.Add(txtCN);
            firstItem = firstItem + 2;
            secondItem = secondItem + 2;
        }
    } else {
        txtDispName = "<tr><td>Group has no members</td>";
        txtCN = "<td>&nbsp;</td></tr>";
        retVal.Add(txtDispName);
        retVal.Add(txtCN);
    }

    // retVal.Add("Array Size is: " + propCount);

    return retVal;
}

public string[] sortLDAPUsers(string[] strArray) {
    Array.Sort(strArray);
    var newArraySize = (strArray.Length * 2);
    string[] itemSeperated = new string[2];
    string[] allSepItems = new string[newArraySize];
    var arrayItemsString = "";
    var xDName = 0;
    var xCName = 1;

    for (var i = 0; i < strArray.Length; i++) {

       itemSeperated = strArray[i].Split('~');
       allSepItems[xDName] = itemSeperated[0];
       allSepItems[xCName] = itemSeperated[1];

       arrayItemsString = arrayItemsString + "Length of allSepItems 
       is: " + allSepItems.Length + " Text is: " + 
       allSepItems[xDName] + " NetId is: " + allSepItems[xCName] + 
       "<br><br>";

       xDName = xDName + 2;
       xCName = xCName + 2;
    }

    return allSepItems;

}

当用户选择包含用户和子组的Active Directory组时,出现以下错误:

异常详细信息:System.NullReferenceException:对象引用未设置为对象的实例。

源错误:

Line 205:        for (var i = 0; i < strArray.Length; i++) {
Line 206:           
Line 207:           itemSeperated = strArray[i].Split('~');
Line 208:           allSepItems[xDName] = itemSeperated[0];
Line 209:           allSepItems[xCName] = itemSeperated[1];

我认为错误与我在GetAllUsersFromGroup()中过滤或获取结果的方式有关。我不知道如何仅从组中吸引用户,而在结果中不包括任何子组。

2 个答案:

答案 0 :(得分:0)

此过滤器(&(objectCategory=Group)(cn=<group>))的问题在于,您正在查询特定的 group 以迭代并抓住所有成员,而与类型/ objectClass无关,因此您将获得用户,组和其他任何内容。

相反,您可以使用适当的过滤器直接请求属于该组的用户

new DirectorySearcher("(&(objectCategory=person)(memberOf=" + groupDN + "))");

请注意,memberOf属性必须与DN匹配,因此给定传入的变量group(如果调用者无法传递实际的组dn),则可能必须先捕获它使用第一个过滤器放置。

随后出现的错误是由于排序而引起的另一个问题,请注释此部分,直到获得正确的结果为止。

答案 1 :(得分:-1)

当您可以让Microsoft Active Directory完成工作时,您不需要那么努力。

带有LDAP过滤器的LDAP搜索请求,过滤条件为Resolve all members (including nested) Security Groups (requires at least Windows 2003 SP2)

(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=YOURDOMAIN,DC=NET) 

这将返回所有“ GroupOne”成员的(objectClass = user)。