我正在使用 spring-security 并希望检索所有用户和所有组以存储在参考表中,这样我就可以快速查找用户而无需查阅 LDAP 目录。我使用以下附加方法创建了一个LdapAuthoritiesPopulator
实现镜像:DefaultLdapAuthoritiesPopulator
public final Collection<GrantedAuthority> getAllAuthorities() {
if (groupSearchBase == null) {
return new HashSet<>();
}
Set<GrantedAuthority> authorities = new HashSet<>();
Set<String> roles = ldapTemplate.searchForSingleAttributeValues(
groupSearchBase,
allAuthorityFilter,
new String[0],
groupRoleAttribute);
for (String role : roles) {
if (convertToUpperCase) {
role = role.toUpperCase();
}
authorities.add(new SimpleGrantedAuthority(rolePrefix + role));
}
return authorities;
}
这现在允许我检索所有组,这allAuthorityFilter
是一个默认为(&(objectClass=group)(objectCategory=group))
.
我现在正试图通过使用以下附加方法创建LdapUserSearch
基于的自定义来与用户实现相同的目标:FilterBasedLdapUserSearch
public List<String> findAllUsers() {
SpringSecurityLdapTemplate template
= new SpringSecurityLdapTemplate(contextSource);
template.setSearchControls(searchControls);
List<String> r = template.search(searchBase,
allUsersFilter,
new AttributesMapper() {
@Override
public Object mapFromAttributes(Attributes atrbts)
throws NamingException {
return (String) atrbts.get(userNameAttribute).get();
}
});
return r;
}
我有两个问题:
- 如果用户列表很大,我会得到
javax.naming.SizeLimitExceededException
我不知道如何解决的问题。 - 我希望此方法返回
DirContextOperations
类似于searchForUser(String)
工作原理的内容,以便LdapUserDetailsMapper
可以重用我的实现以返回所有用户属性。
我发现文档LdapTemplate
有点毛茸茸,并且无法找到我想要的答案,任何帮助将不胜感激。
更新:我已经解决了上面的第(2)点
public List<UserDetails> getAllUserDetails(boolean includeAuthorities) {
List<UserDetails> r = new ArrayList<>();
for (DirContextOperations ctx : userSearch.findAllUserOperations()) {
try {
Attribute att = ctx.getAttributes().get(usernameAttribute);
String username = (String) att.get();
r.add(userMapper.mapUserFromContext(
ctx,
username,
includeAuthorities
? authPop.getGrantedAuthorities(ctx, username)
: Collections.<GrantedAuthority>emptySet()));
} catch (NamingException ex) {
LOG.warn("Username attribute " + usernameAttribute + " not found!");
}
}
return r;
}
在我的UserSearch
实现中,我有:
public List<DirContextOperations> findAllUserOperations() {
SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(contextSource);
template.setSearchControls(searchControls);
return template.search(searchBase,
allUsersFilter, new ContextMapper() {
@Override
public Object mapFromContext(Object o) {
return (DirContextOperations) o;
}
});
}
但是我还没有解决第 1 点。如果我需要以某种方式对此进行批处理,那么只要有一种方法可以告诉LdapTemplate
在后续调用中从哪里恢复就可以了。