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

如何使用Novell.Directory.Ldap.NETStandard查询LDAP用户所属用户组

Novell.Directory.Ldap.NETStandard 查询AD用户所属组实现方案

方案1:读取用户memberOf属性(查询直接所属组)

该方案实现简单,适合不需要统计嵌套组的场景,仅需调整原有搜索参数,指定返回memberOf属性即可,修改后代码如下:

use connection = new LdapConnection()
connection.Connect(credentials.host, LdapConnection.DefaultPort)
connection.Bind($"{credentials.domain}\\{credentials.username}", credentials.password)
match connection.Connected with
| true ->   
    // 提取域根DN作为搜索根路径
    let domainDn = connection.GetSchemaDn().Split(',').Skip(1) |> String.concat ","
    // 匹配指定SAM账号的用户过滤器
    let userFilter = $"(SAMAccountName={credentials.username})"
    // 指定返回属性,加入memberOf获取用户直接所属组
    let returnAttrs = [|"samAccountName";"displayName";"memberOf"|]
    // 搜索范围设置为ScopeSub遍历整个域下的对象
    let searchResults = connection.Search(domainDn, LdapConnection.ScopeSub, userFilter, returnAttrs, false)
    // 提取所有组DN
    let userDirectGroups = 
        [ while searchResults.hasMore() do
            let userEntry = searchResults.next()
            let memberOfAttr = userEntry.getAttribute("memberOf")
            if memberOfAttr <> null then
                yield! memberOfAttr.StringValues ]
    return (Some userDirectGroups, String.Empty)
| false -> 
    return (None, $"Cannot connect to domain {credentials.domain} with user {credentials.username}")

方案2:递归查询所有所属组(含嵌套组)

如果需要查询用户所有所属组,包括用户所在组的父组等嵌套关系,可以使用AD专属的LDAP扩展匹配规则1.2.840.113556.1.4.1941实现,示例代码如下:

use connection = new LdapConnection()
connection.Connect(credentials.host, LdapConnection.DefaultPort)
connection.Bind($"{credentials.domain}\\{credentials.username}", credentials.password)
match connection.Connected with
| true ->   
    let domainDn = connection.GetSchemaDn().Split(',').Skip(1) |> String.concat ","
    let userFilter = $"(SAMAccountName={credentials.username})"
    let userReturnAttrs = [|"distinguishedName"|]
    let userSearchResults = connection.Search(domainDn, LdapConnection.ScopeSub, userFilter, userReturnAttrs, false)
    
    if userSearchResults.hasMore() then
        let userDn = userSearchResults.next().DN
        // 递归匹配所有包含该用户的组
        let nestedGroupFilter = $"(& (objectCategory=group) (member:1.2.840.113556.1.4.1941:={userDn}))"
        let groupReturnAttrs = [|"name";"distinguishedName"|]
        let groupSearchResults = connection.Search(domainDn, LdapConnection.ScopeSub, nestedGroupFilter, groupReturnAttrs, false)
        let allUserGroups = 
            [ while groupSearchResults.hasMore() do
                let groupEntry = groupSearchResults.next()
                yield groupEntry.getAttribute("name").StringValue ]
        return (Some allUserGroups, String.Empty)
    else
        return (None, "User not found")
| false -> 
    return (None, $"Cannot connect to domain {credentials.domain} with user {credentials.username}")

注意事项

  • 绑定的账号需要拥有对应域的用户、组查询权限,否则会返回空结果
  • 多域林环境下需要连接全局编录服务器(端口3268)实现跨域组查询
  • memberOf属性默认不包含用户主组(如Domain Users),如果需要获取主组,可额外查询用户的primaryGroupID属性,匹配对应组的primaryGroupToken属性即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:15:05