如何修改代码仅从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; }
额外优化建议
- 替换ArrayList为泛型集合:用
List<string>替代ArrayList,获得更好的类型安全性和性能:List<string> userNames = new List<string>(); // 最后返回时可转为ArrayList(如果需要兼容原有代码): return new ArrayList(userNames); - 提升查询性能:如果组内成员数量较多,建议使用批量查询的方式,避免逐个创建
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
相关产品推荐
相关产品推荐

