Filter granted authorities by checking memberOf

266 Views Asked by At

I'm sorry if it's a duplicate, but I've been really strugling with this topic. I need to filter search result of memberOf. I'm trying to map those results into Granted Authorities. I'm basing my solution on this repo https://github.com/SNCF-SIV/spring-security-rest-jwt-ldap. A piece of code below works just fine:

@Bean
LdapAuthoritiesPopulator ldapAuthoritiesPopulator() throws Exception {

    class MyLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {

        final SpringSecurityLdapTemplate ldapTemplate;
        public final String[] GROUP_ATTRIBUTE = {"cn"};
        public final String GROUP_MEMBER_OF = "memberof";

        MyLdapAuthoritiesPopulator(ContextSource contextSource) {
            ldapTemplate = new SpringSecurityLdapTemplate(contextSource);
        }

        @Override
        public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {

            String[] groupDns = userData.getStringAttributes(GROUP_MEMBER_OF);

            String roles = Stream.of(groupDns).map(groupDn -> {
                LdapName groupLdapName = (LdapName) ldapTemplate.retrieveEntry(groupDn, GROUP_ATTRIBUTE).getDn();

                return groupLdapName.getRdns().stream().map(Rdn::getValue).reduce((a, b) -> b).orElse(null);
            }).map(x -> (String)x).collect(Collectors.joining(","));

            return AuthorityUtils.commaSeparatedStringToAuthorityList(roles);
        }
    }

    return new MyLdapAuthoritiesPopulator(contextSource());
}

With each authentication request it maps user's memberOf into his/her authority. But it maps every group a user is in. I want to filter them, for instance get only groups starting with:
cn=ccms,cn=groups,o=company
It would return groups (and thus grant authority) for
cn=test,cn=ccms,cn=groups,o=company,
cn=prod,cn=ccms,cn=groups,o=company,
but not for
cn=admins,cn=jira,cn=groups,o=company.

Can you elaborate on how to write a simple filter matching the piece of code above? I have a feeling it's an oneliner.

EDIT: I know I could just easily compare strings (like return only those which contain cn=ccms,cn=groups,o=company), but maybe there's a little cleaner way

1

There are 1 best solutions below

0
On

For now I've done it by adding:

    public final String GROUP_FILTER = "cn=ccms,cn=groups,o=company";

    final List<String> filteredGroupDns = Arrays.stream(groupDns)
                                                .filter(g -> g.toLowerCase().contains(GROUP_FILTER.toLowerCase()))
                                                .collect(Collectors.toList());

I'm not gonna accept this answer yet. I you have any more LDAP-related solution (group search filter), please feel free to share.