简体   繁体   中英

How to obtain all LDAP groups in spring security

How to obtain all Active Directory groups (Not just related to a current user)? I'm using spring security ldap. Could you provide some examples?

Spring Security LDAP is great if you want to authenticate users, but if you just need to query LDAP (in this case for all groups), then Spring LDAP (not to be confused with Spring Security LDAP ) is better suited for your purposes.

Example:

import static org.springframework.ldap.query.LdapQueryBuilder.query;

LdapTemplate ldapTemplate; // Injected via Spring

// Using Java 8 lambda expressions
ldapTemplate.search(
    query().where("objectclass").is("group"),
    (AttributesMapper<String>) attributes -> attributes.get("cn").get().toString()
);

What you can do is write an implementation of LdapAuthoritiesPopulator that matches the DefaultLdapAuthoritiesPopulator implementation with an extra method to retrieve all roles.

public class ExtendedLdapAuthoritiesPopulator
        implements LdapAuthoritiesPopulator {

    // Copy implementation of DefaultLdapAuthoritiesPopulator (omitted).

    private String allAuthorityFilter
        = "(&(objectClass=group)(objectCategory=group))";
    public void setAllAuthorityFilter(String allAuthorityFilter) {
        Assert.notNull(allAuthorityFilter,
                       "allAuthorityFilter must not be null");
        this.allAuthorityFilter = allAuthorityFilter;
    }

    public final Collection<GrantedAuthority> getAllAuthorities() {
        if (groupSearchBase == null) {
            return new HashSet<>();
        }
        Set<GrantedAuthority> authorities = new HashSet<>();
        if (logger.isDebugEnabled()) {
            logger.debug("Searching for all roles with filter '"
                         + allAuthorityFilter + "' in search base '"
                         + groupSearchBase + "'");
        }
        Set<String> roles = ldapTemplate.searchForSingleAttributeValues(
                groupSearchBase,
                allAuthorityFilter,
                new String[0],
                groupRoleAttribute);
        if (logger.isDebugEnabled()) {
            logger.debug("Roles from search: " + roles);
        }
        for (String role : roles) {
            if (convertToUpperCase) {
                role = role.toUpperCase();
            }
            authorities.add(new SimpleGrantedAuthority(rolePrefix + role));
        }
        return authorities;
    }

}

In your spring security configuration change the DefaultLdapAuthoritiesPopulator to your new implementation.

An additional property can set the AllAuthorityFilter which filters which groups will be returned.

You may prefer your implementation to just retrieve the String based role names instead of the GrantedAuthority instances.

Getting all LDAP Groups might require different authentication than getting de groups of a user that logs in. One can user Spring LDAPTemplate.

import java.util.List;
import javax.naming.directory.SearchControls;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;

public class LDAPListGroups {

    public static void main(String[] args) throws Exception {

        LdapContextSource ldapContextSource = new LdapContextSource();
        //LDAP URL
        ldapContextSource.setUrl("ldap://localhost:10389/dc=example,dc=com");
        //Authenticate as User that has access to this node in LDAP
        ldapContextSource.setUserDn("uid=admin,ou=system");
        ldapContextSource.setPassword("secret");
        ldapContextSource.afterPropertiesSet();
        LdapTemplate ldapTemplate = new LdapTemplate(ldapContextSource);
        ldapTemplate.afterPropertiesSet();

        GroupAttributesMapper mapper = new GroupAttributesMapper();
        SearchControls controls = new SearchControls();
        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter("objectclass", "groupOfNames"));

        List<Group> groups = ldapTemplate.search("ou=groups", filter.encode(), controls, mapper);
        for (Group group:groups)
        {
            System.out.println(group.getLongID());
        }
    }
}



import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.support.LdapEncoder;

public class GroupAttributesMapper implements AttributesMapper<Group> {

    public Group mapFromAttributes(Attributes attributes) throws NamingException {
        Group groupObject = new Group(attributes.get("cn").get().toString().toUpperCase());
        NamingEnumeration<?> it = attributes.get("member").getAll();
        while (it.hasMoreElements())
        {
            String elem = (String) it.next();
            elem = elem.substring(elem.indexOf("cn=")+3);
            elem = elem.substring(0,elem.indexOf(","));
            elem = LdapEncoder.nameDecode(elem);
            groupObject.addMember(elem);
        }
        return groupObject;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM