在.NET Core中使用Novell.Directory.Ldap获取LDAP用户组报错的排查与解决
问题分析与解决方案
错误原因
你遇到的memberOf不存在问题,核心原因是Apache Directory Server(你用的Apache Directory Studio对应的LDAP服务器)默认不会自动维护memberOf这个反向属性。memberOf是Active Directory(AD)常用的反向关联属性,但多数开源LDAP服务器(包括Apache DS)默认只在组对象中用member属性存储成员DN,不会在用户对象上自动生成memberOf属性。
另外你的代码还有两个小问题:
- 搜索范围用了
ScopeSub,但你已经指定了用户的完整DN作为搜索基,应该用ScopeBase(只查询当前对象),避免不必要的子树搜索。 - 搜索时传
null表示返回所有属性,但即使这样,服务器没生成memberOf的话也不会返回。
解决方案
方案1:正向查询组对象(推荐,无需修改服务器配置)
直接搜索所有组,过滤出包含该用户的组,这是LDAP通用的做法,无需依赖反向属性:
using (var connection = new LdapConnection() { SecureSocketLayer = false }) { connection.Connect(_ldapSettings.Server, _ldapSettings.Port); if (_ldapSettings.UseSSL) connection.StartTls(); connection.Bind("cn=sample,ou=users,ou=system", password); // 搜索所有组,过滤条件为成员包含目标用户 ILdapSearchResults searchResults = connection.Search( "ou=groups,ou=system", // 替换成你的组所在的根DN LdapConnection.ScopeSub, "(member=cn=sample,ou=users,ou=system)", // 目标用户的完整DN new string[] { "cn", "dn" }, // 指定要返回的属性,比如组名和DN false ); while (searchResults.HasMore()) { LdapEntry groupEntry = searchResults.Next(); Console.WriteLine($"组DN: {groupEntry.Dn}, 组名: {groupEntry.GetAttribute("cn")?.StringValue}"); } return true; }
方案2:开启Apache DS的memberOf反向属性支持
如果一定要用memberOf属性,需要在Apache Directory Studio中配置服务器的反向属性插件:
- 打开Apache Directory Studio,连接到你的服务器。
- 右键点击服务器 -> Open Configuration。
- 切换到Plugins标签,找到并启用
memberOf插件。 - 配置插件的参数(默认配置一般适配
groupOfNames类,无需额外修改)。 - 重启LDAP服务器,之后用户对象就会自动生成
memberOf属性,你的原有代码修改搜索范围为ScopeBase后就能正常使用:
// 修改搜索部分的代码 ILdapSearchResults searchResults = connection.Search( "cn=sample,ou=users,ou=system", LdapConnection.ScopeBase, // 只查询当前用户对象 "(objectClass=*)", new string[] { "memberOf" }, // 只返回需要的属性,提升效率 false );
内容的提问来源于stack exchange,提问作者Anthony Cuartero
相关产品推荐
相关产品推荐

