You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改代码仅从Active Directory中获取用户而非组

如何修改C#代码从Active Directory组中仅获取用户而非组

当前代码直接读取AD组的member属性,该属性包含组内所有成员(包括用户和嵌套组),要只保留用户,需要对每个成员的对象类型做校验。以下是具体修改方案:

核心修改思路

遍历每个成员的Distinguished Name时,创建对应的DirectoryEntry对象,通过objectCategory属性判断是否为用户(objectCategory是单值属性,比多值的objectClass更可靠)。

修改后的完整代码

public ArrayList GetADGroupUsers(string groupNames)
{
    string[] strGrpNames = groupNames.Split(new char[] { ',' });
    ArrayList userNames = new ArrayList();            
    string ADPassword = ConfigurationManager.AppSettings["ADPassword"];
    IAAccess_Transaction.drms_dataaccess drmsda = new IAAccess_Transaction.drms_dataaccess();
      
    string domainAndUsername = ConfigurationManager.AppSettings["domain"] + @"\\" + ConfigurationManager.AppSettings["ADUserName"];
    string decriptedADPassword = drmsda.Decrypt(ADPassword);
    DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, decriptedADPassword);

    // 强制绑定到原生AdsObject完成认证
    object obj = entry.NativeObject;

    DirectorySearcher search = new DirectorySearcher(entry);

    foreach (string strGrp in strGrpNames)
    {
        search.Filter = String.Format("(cn={0})", strGrp);
        search.PropertiesToLoad.Add("member");

        SearchResult result = search.FindOne();

        if (result != null)
        {
            foreach (string memberDn in result.Properties["member"])
            {
                // 创建成员对应的DirectoryEntry
                using (DirectoryEntry memberEntry = new DirectoryEntry(
                    $"LDAP://{memberDn}", 
                    domainAndUsername, 
                    decriptedADPassword))
                {
                    try
                    {
                        // 获取objectCategory属性,判断是否为用户(Person类)
                        string objectCategory = memberEntry.Properties["objectCategory"].Value.ToString();
                        if (objectCategory.Contains("CN=Person,"))
                        {
                            userNames.Add(memberDn);
                        }
                    }
                    catch (Exception ex)
                    {
                        // 处理权限不足或对象不存在的异常
                        // 可根据需求添加日志记录
                    }
                }
            }
        }
    }
    return userNames;
}

额外优化建议

  1. 替换ArrayList为泛型集合:用List<string>替代ArrayList,获得更好的类型安全性和性能:
    List<string> userNames = new List<string>();
    // 最后返回时可转为ArrayList(如果需要兼容原有代码):
    return new ArrayList(userNames);
    
  2. 提升查询性能:如果组内成员数量较多,建议使用批量查询的方式,避免逐个创建DirectoryEntry的开销。可以构造一个过滤条件,一次性查询所有成员的类型:
    // 收集所有成员DN
    List<string> memberDns = new List<string>();
    foreach (string memberDn in result.Properties["member"])
    {
        memberDns.Add(memberDn);
    }
    // 构造批量查询过滤条件(转义DN中的特殊字符)
    string filter = $"(|{string.Join("", memberDns.Select(dn => 
        $"(&objectCategory=person)(distinguishedName={dn.Replace("(", "\\28").Replace(")", "\\29")})"))})";
    DirectorySearcher memberSearch = new DirectorySearcher(entry, filter, new[] {"distinguishedName"});
    foreach (SearchResult memberResult in memberSearch.FindAll())
    {
        userNames.Add(memberResult.Properties["distinguishedName"][0].ToString());
    }
    

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 16:40:26