我正在使用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;
}
});
}
但是我还没有解决第一点。如果我需要以某种方式批量处理,那么只要有一种方法可以告诉LdapTemplate
在后续调用中恢复的位置,那就没问题了。