ASP.NET中从LDAP获取用户所属组失败:SearchResultEntry为空求助
问题分析与解决
你的代码里的SearchRequest构造参数使用完全错误,第二个参数是LDAP筛选器而非组名称,同时用户的DN格式也存在问题(DC=my.server需拆分为DC=my,DC=server这类标准格式),这导致查询无结果返回。以下是两种正确的实现方案:
方法1:直接获取用户所有直接所属组
通过查询用户对象的memberOf属性,直接获取所有直接归属的组:
LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("my.server", 636)); var networkCredential = new NetworkCredential("username", "password"); ldapConnection.SessionOptions.SecureSocketLayer = true; ldapConnection.SessionOptions.ProtocolVersion = 3; ldapConnection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback); ldapConnection.AuthType = AuthType.Negotiate; ldapConnection.Bind(networkCredential); // 正确的用户DN格式示例:CN=用户名,OU=用户组,DC=my,DC=server string userDn = "CN=username,OU=Users,DC=my,DC=server"; // 查询用户对象,仅返回memberOf属性 SearchRequest searchRequest = new SearchRequest( userDn, "(objectClass=user)", SearchScope.Base, "memberOf" ); SearchResponse searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest); if (searchResponse.Entries.Count > 0) { SearchResultEntry userEntry = searchResponse.Entries[0]; if (userEntry.Attributes.Contains("memberOf")) { foreach (var groupDn in userEntry.Attributes["memberOf"].GetValues(typeof(string))) { ListBox2.Items.Add(groupDn.ToString()); // 可在此判断是否为目标组: // if (groupDn.ToString().Equals("CN=mygroup,OU=Groups,DC=my,DC=server", StringComparison.OrdinalIgnoreCase)) // { // // 用户属于该组 // } } } }
方法2:检查用户是否属于指定组(支持嵌套组)
如果需要验证用户是否属于目标组(包含嵌套组场景,即用户在子组、子组在目标组的情况),使用LDAP_MATCHING_RULE_IN_CHAIN筛选器:
LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("my.server", 636)); var networkCredential = new NetworkCredential("username", "password"); ldapConnection.SessionOptions.SecureSocketLayer = true; ldapConnection.SessionOptions.ProtocolVersion = 3; ldapConnection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback); ldapConnection.AuthType = AuthType.Negotiate; ldapConnection.Bind(networkCredential); // 目标组的DN string targetGroupDn = "CN=mygroup,OU=Groups,DC=my,DC=server"; // 用户的登录名(sAMAccountName) string userSamAccountName = "username"; // 使用IN_CHAIN筛选器检查用户是否在组内(含嵌套) SearchRequest searchRequest = new SearchRequest( "DC=my,DC=server", // 搜索根节点 $"(&(objectClass=user)(sAMAccountName={userSamAccountName})(memberOf:1.2.840.113556.1.4.1941:={targetGroupDn}))", SearchScope.Subtree ); SearchResponse searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest); // 有结果则说明用户属于该组 bool isInGroup = searchResponse.Entries.Count > 0; ListBox2.Items.Add(isInGroup ? "用户属于目标组" : "用户不属于目标组");
关键注意事项
- DN格式规范:用户和组的DN必须符合LDAP标准,比如域名
my.server对应的DC段是DC=my,DC=server,而非DC=my.server。 - 筛选器语法:LDAP筛选器需遵循RFC规范,不能直接传入组名作为筛选条件。
- 嵌套组场景:仅需直接组关系用方法1即可,需要包含嵌套组则用方法2的
IN_CHAIN筛选器。
内容的提问来源于stack exchange,提问作者Hercules
相关产品推荐
相关产品推荐

