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;
}
これには2つの問題があります。
- ユーザーリストが大きい場合、
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
何らかの方法でこれをバッチ処理する必要がある場合は、後続の呼び出しで再開する場所を伝える方法がある限り問題ありません。