2

我正在使用 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;
}

我有两个问题:

  1. 如果用户列表很大,我会得到javax.naming.SizeLimitExceededException我不知道如何解决的问题。
  2. 我希望此方法返回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在后续调用中从哪里恢复就可以了。

4

0 回答 0