4

I am using Spring Security 3.2.5 with Java config and LDAP authentication/authorization.

We have a requirement to search for groups in two separate trees in LDAP.

ou=groups

and

ou=Groups,ou=webapps,ou=Applications

I have searched and have been unable to find any information on this topic.

This is my current code which is working fine:

@Autowired
public void configureGlobal(UserDetailsContextMapper userDetailsContextMapper, LdapContextSource contextSource, AuthenticationManagerBuilder builder) throws Exception {


    builder
    .ldapAuthentication()
        .userDetailsContextMapper(userDetailsContextMapper)
        .contextSource(contextSource)
        .userSearchFilter("cn={0}")
        .userSearchBase("ou=Users")
        .groupSearchBase("ou=groups");


}

I want to do something like this:

    builder
    .ldapAuthentication()
        .userDetailsContextMapper(userDetailsContextMapper)
        .contextSource(contextSource)
        .userSearchFilter("cn={0}")
        .userSearchBase("ou=Users")
        .groupSearchBase("ou=groups")
        .groupSearchBase("ou=Groups,ou=webapps,ou=Applications");

Which understandably does not work.

Anyone have any pointers on where to start?

Sean Newby
  • 41
  • 3

1 Answers1

3

My solution was to create an implementation of org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator which can call multiple instances of LdapAuthoritiesPopulator. Then create one LdapAuthoritiesPopulatorfor each 'groupSearchBase' that I wanted to query.

@Autowired
public void configureGlobal(UserDetailsContextMapper userDetailsContextMapper, LdapContextSource contextSource, AuthenticationManagerBuilder builder) throws Exception {

    MultipleLdapAuthoritiesPopulator multipleLdapAuthoritiesPopulator = new MultipleLdapAuthoritiesPopulator(
        new DefaultLdapAuthoritiesPopulator(contextSource, "ou=Groups,ou=webapps,ou=Applications"),
        new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups"));

    builder
        .ldapAuthentication()
            .ldapAuthoritiesPopulator(multipleLdapAuthoritiesPopulator)
            .userDetailsContextMapper(userDetailsContextMapper) 
            .contextSource(contextSource)
            .userSearchFilter("cn={0}")
            .userSearchBase("ou=Users");
}

class MultipleLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
    private List<LdapAuthoritiesPopulator> authoritiesPopulators;

    public MultipleLdapAuthoritiesPopulator(LdapAuthoritiesPopulator...authoritiesPopulators) {
        this.authoritiesPopulators = asList(authoritiesPopulators);
    }

    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
        List<GrantedAuthority> grantedAuthorities = authoritiesPopulators.stream()
            .map(authPopulator -> authPopulator.getGrantedAuthorities(userData, username))
            .flatMap(Collection::stream)
            .collect(Collectors.toList());

        return grantedAuthorities;
    }
}
Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
HenrikG
  • 31
  • 4