如何在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
相关产品推荐
相关产品推荐

