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

如何在Spring LDAP认证中获取isMemberOf等Operational Attrs

我之前在项目里也遇到过完全一样的问题!操作属性(Operational Attributes)确实不会跟着常规属性一起返回,LDAP服务器只会返回你明确请求的属性,尤其是像isMemberOf这种特殊的操作属性。结合你管理员给的Shell命令思路——也就是显式指定要查询的属性——在Spring LDAP里可以这么解决:

1. 如果你用Spring Security LDAP做认证

这种场景下,需要在认证流程中明确告诉LDAP要返回isMemberOf属性,有两种常用方式:

方式一:自定义UserDetailsContextMapper获取属性

在映射LDAP用户到Spring的UserDetails时,主动从DirContextOperations中提取isMemberOf:

@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
    return new LdapUserDetailsMapper() {
        @Override
        public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
            // 主动获取isMemberOf属性,这里要确保LDAP已经返回了该属性
            String[] memberOfValues = ctx.getStringAttributes("isMemberOf");
            
            // 可以封装到自定义的User类中,方便后续使用
            CustomUser customUser = new CustomUser(username, "", authorities);
            if (memberOfValues != null) {
                customUser.setMemberOf(Arrays.asList(memberOfValues));
            }
            return customUser;
        }
    };
}

方式二:在Authenticator中配置SearchControls

如果你的认证是基于搜索用户的(比如用SearchAuthenticator),需要在搜索控制中指定返回的属性包含isMemberOf:

@Bean
public BindAuthenticator authenticator(ContextSource contextSource) {
    SearchAuthenticator searchAuthenticator = new SearchAuthenticator(contextSource);
    searchAuthenticator.setSearchBase("ou=users");
    searchAuthenticator.setSearchFilter("uid={0}"); // 你的用户搜索过滤规则

    // 配置搜索控制,明确指定要返回的属性
    SearchControls searchControls = new SearchControls();
    searchControls.setReturningAttributes(new String[]{"cn", "mail", "isMemberOf"}); // 加上isMemberOf
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
    searchAuthenticator.setSearchControls(searchControls);
    return searchAuthenticator;
}

2. 如果你直接用LdapTemplate查询用户数据

这种场景更直接,在构建SearchControls时指定要返回isMemberOf即可:

public List<String> getUserMemberOf(String userId) {
    SearchControls searchControls = new SearchControls();
    // 关键:明确指定要返回的属性包含isMemberOf
    searchControls.setReturningAttributes(new String[]{"isMemberOf"});
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    String searchFilter = "uid=" + userId;
    List<List<String>> result = ldapTemplate.search(
            "ou=users", // 你的用户根目录
            searchFilter,
            searchControls,
            (Attributes attrs) -> {
                Attribute memberOfAttr = attrs.get("isMemberOf");
                if (memberOfAttr != null) {
                    return Collections.list(memberOfAttr.getAll()).stream()
                            .map(Object::toString)
                            .collect(Collectors.toList());
                }
                return Collections.emptyList();
            }
    );

    return result.isEmpty() ? Collections.emptyList() : result.get(0);
}

本质上,这和你管理员给的Shell命令是一个逻辑——比如他的命令可能是:

ldapsearch -x -D "cn=admin,dc=yourcompany,dc=com" -W -b "uid=youruser,ou=users,dc=yourcompany,dc=com" "isMemberOf"

这里最后的isMemberOf就是明确告诉LDAP服务器只返回这个属性,对应到Spring里就是通过SearchControls.setReturningAttributes()来指定。

内容的提问来源于stack exchange,提问作者Batu.Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:28:14