CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-security--spring-security-ldap

Spring Security LDAP module providing comprehensive LDAP authentication and authorization capabilities for enterprise applications

Pending
Overview
Eval results
Files

authorities.mddocs/

Authorities Population

Authority and role mapping from LDAP groups and attributes with customizable population strategies for complex authorization scenarios.

Capabilities

LdapAuthoritiesPopulator

Strategy interface for populating user authorities from LDAP directory information.

/**
 * Strategy interface for retrieving user authorities from LDAP directory entries
 */
public interface LdapAuthoritiesPopulator {
    /**
     * Retrieves the granted authorities for a user based on their LDAP entry
     * @param userData the LDAP context operations containing user information
     * @param username the username of the authenticated user
     * @return collection of granted authorities for the user
     */
    Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);
}

DefaultLdapAuthoritiesPopulator

Default implementation that populates authorities from LDAP group memberships and user attributes.

/**
 * Default LDAP authorities populator that retrieves user authorities from LDAP group memberships
 * and optionally from user attributes
 */
public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator, InitializingBean, MessageSourceAware {
    /**
     * Creates an authorities populator with context source and group search base
     * @param contextSource the LDAP context source
     * @param groupSearchBase the base DN for searching groups (e.g., "ou=groups")
     */
    public DefaultLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase);
    
    /**
     * Retrieves granted authorities from LDAP groups and user attributes
     * @param userData the user's LDAP context operations
     * @param username the username
     * @return collection of granted authorities
     */
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);
    
    /**
     * Sets the LDAP filter for searching groups that contain the user
     * @param groupSearchFilter filter with {0} placeholder for user DN (default: "member={0}")
     */
    public void setGroupSearchFilter(String groupSearchFilter);
    
    /**
     * Sets the attribute name that contains the role/authority name in group entries
     * @param groupRoleAttribute attribute name (default: "cn")
     */
    public void setGroupRoleAttribute(String groupRoleAttribute);
    
    /**
     * Sets the prefix to add to role names extracted from groups
     * @param rolePrefix prefix to add (default: "ROLE_")
     */
    public void setRolePrefix(String rolePrefix);
    
    /**
     * Sets whether to convert role names to uppercase
     * @param convertToUpperCase true to convert to uppercase (default: true)
     */
    public void setConvertToUpperCase(boolean convertToUpperCase);
    
    /**
     * Sets the scope for group searches
     * @param groupSearchSubtree true to search subtree, false for one level (default: false)
     */
    public void setSearchSubtree(boolean groupSearchSubtree);
    
    /**
     * Sets a user attribute that should be used as an additional authority
     * @param attributeName the name of the user attribute containing role information
     */
    public void setGroupRoleAttribute(String attributeName);
    
    /**
     * Sets the default role to assign to all users
     * @param defaultRole the default role name
     */
    public void setDefaultRole(String defaultRole);
    
    /**
     * Sets whether to ignore partial result exceptions during group searches
     * @param ignore true to ignore partial result exceptions
     */
    public void setIgnorePartialResultException(boolean ignore);
}

Usage Examples:

// Basic authorities populator
DefaultLdapAuthoritiesPopulator authoritiesPopulator = 
    new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups");

// Customized group search
authoritiesPopulator.setGroupSearchFilter("member={0}");
authoritiesPopulator.setGroupRoleAttribute("cn");
authoritiesPopulator.setRolePrefix("ROLE_");
authoritiesPopulator.setConvertToUpperCase(true);

// Search configuration
authoritiesPopulator.setSearchSubtree(true);
authoritiesPopulator.setIgnorePartialResultException(true);

// Default role for all users
authoritiesPopulator.setDefaultRole("USER");

UserDetailsServiceLdapAuthoritiesPopulator

Authorities populator that delegates to a UserDetailsService for authority retrieval.

/**
 * LdapAuthoritiesPopulator that obtains authorities from a UserDetailsService
 */
public class UserDetailsServiceLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
    /**
     * Creates a populator with the specified UserDetailsService
     * @param userService the UserDetailsService to delegate to
     */
    public UserDetailsServiceLdapAuthoritiesPopulator(UserDetailsService userService);
    
    /**
     * Gets authorities by loading UserDetails for the username
     * @param userData the LDAP context operations (ignored)
     * @param username the username to look up
     * @return collection of authorities from UserDetailsService
     */
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);
}

NestedLdapAuthoritiesPopulator

Authorities populator that can recursively search nested LDAP groups.

/**
 * LDAP authorities populator that can recursively search static nested groups
 */
public class NestedLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator {
    /**
     * Creates a nested authorities populator
     * @param contextSource the LDAP context source
     * @param groupSearchBase the base DN for group searches
     */
    public NestedLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase);
    
    /**
     * Sets the maximum search depth for nested groups
     * @param maxSearchDepth maximum depth (default: 10)
     */
    public void setMaxSearchDepth(int maxSearchDepth);
    
    /**
     * Sets additional search filters for nested group searches
     * @param additionalFilters map of filter names to filter expressions
     */
    public void setAdditionalFilters(Map<String, String> additionalFilters);
    
    /**
     * Retrieves authorities including nested group memberships
     * @param userData the user's LDAP context
     * @param username the username
     * @return collection of authorities from direct and nested groups
     */
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);
}

NullLdapAuthoritiesPopulator

No-operation authorities populator that returns empty authorities collection.

/**
 * Implementation of LdapAuthoritiesPopulator that returns an empty collection of authorities
 * Useful when authorities are managed outside of LDAP or when no role-based authorization is needed
 */
public class NullLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
    /**
     * Returns an empty collection of granted authorities
     * @param userData LDAP context operations for the user (ignored)
     * @param username the username (ignored)
     * @return empty collection of authorities
     */
    public Collection<GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);
}

Custom Authority Population Strategies

User Attribute-Based Authorities

/**
 * Example custom authorities populator that extracts roles from user attributes
 */
public class UserAttributeAuthoritiesPopulator implements LdapAuthoritiesPopulator {
    private String roleAttributeName = "employeeType";
    private String rolePrefix = "ROLE_";
    
    /**
     * Sets the user attribute name containing role information
     * @param roleAttributeName the attribute name
     */
    public void setRoleAttributeName(String roleAttributeName);
    
    /**
     * Sets the prefix for role names
     * @param rolePrefix the role prefix
     */
    public void setRolePrefix(String rolePrefix);
    
    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(
            DirContextOperations userData, String username) {
        
        Set<GrantedAuthority> authorities = new HashSet<>();
        
        // Extract roles from user attributes
        String[] roles = userData.getStringAttributes(roleAttributeName);
        if (roles != null) {
            for (String role : roles) {
                authorities.add(new SimpleGrantedAuthority(rolePrefix + role.toUpperCase()));
            }
        }
        
        return authorities;
    }
}

Composite Authorities Populator

/**
 * Composite authorities populator that combines multiple population strategies
 */
public class CompositeAuthoritiesPopulator implements LdapAuthoritiesPopulator {
    private List<LdapAuthoritiesPopulator> populators;
    
    /**
     * Creates a composite populator with the specified delegate populators
     * @param populators list of authorities populators to delegate to
     */
    public CompositeAuthoritiesPopulator(List<LdapAuthoritiesPopulator> populators);
    
    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(
            DirContextOperations userData, String username) {
        
        Set<GrantedAuthority> allAuthorities = new HashSet<>();
        
        // Collect authorities from all populators
        for (LdapAuthoritiesPopulator populator : populators) {
            Collection<? extends GrantedAuthority> authorities = 
                populator.getGrantedAuthorities(userData, username);
            allAuthorities.addAll(authorities);
        }
        
        return allAuthorities;
    }
}

Configuration Examples

Standard Group-Based Authorization

@Configuration
public class LdapAuthoritiesConfig {
    
    @Bean
    public DefaultLdapAuthoritiesPopulator authoritiesPopulator() {
        DefaultLdapAuthoritiesPopulator populator = 
            new DefaultLdapAuthoritiesPopulator(contextSource(), "ou=groups");
        
        // Configure group search
        populator.setGroupSearchFilter("member={0}");
        populator.setGroupRoleAttribute("cn");
        
        // Role configuration
        populator.setRolePrefix("ROLE_");
        populator.setConvertToUpperCase(true);
        populator.setDefaultRole("USER");
        
        // Search configuration
        populator.setSearchSubtree(true);
        populator.setIgnorePartialResultException(true);
        
        return populator;
    }
}

Active Directory Group Membership

@Bean
public DefaultLdapAuthoritiesPopulator activeDirectoryAuthorities() {
    DefaultLdapAuthoritiesPopulator populator = 
        new DefaultLdapAuthoritiesPopulator(contextSource(), "");
        
    // Active Directory uses memberOf attribute
    populator.setGroupSearchFilter("(&(objectClass=group)(member={0}))");
    populator.setGroupRoleAttribute("cn");
    populator.setSearchSubtree(true);
    
    // Active Directory specific settings
    populator.setRolePrefix("ROLE_");
    populator.setConvertToUpperCase(true);
    
    return populator;
}

Multi-Level Group Hierarchy

@Component
public class HierarchicalGroupsPopulator implements LdapAuthoritiesPopulator {
    
    private final SpringSecurityLdapTemplate ldapTemplate;
    private final String groupSearchBase;
    
    public HierarchicalGroupsPopulator(SpringSecurityLdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
        this.groupSearchBase = "ou=groups";
    }
    
    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(
            DirContextOperations userData, String username) {
        
        Set<GrantedAuthority> authorities = new HashSet<>();
        Set<String> processedGroups = new HashSet<>();
        
        // Find direct group memberships
        Set<String> directGroups = findDirectGroups(userData.getDn().toString());
        
        // Recursively find parent groups
        for (String groupDn : directGroups) {
            collectGroupHierarchy(groupDn, authorities, processedGroups);
        }
        
        return authorities;
    }
    
    private Set<String> findDirectGroups(String userDn) {
        return ldapTemplate.searchForSingleAttributeValues(
            groupSearchBase, 
            "member={0}", 
            new Object[]{userDn}, 
            "distinguishedName"
        );
    }
    
    private void collectGroupHierarchy(String groupDn, Set<GrantedAuthority> authorities, 
            Set<String> processedGroups) {
        
        if (processedGroups.contains(groupDn)) {
            return; // Avoid circular references
        }
        processedGroups.add(groupDn);
        
        try {
            // Get group information
            DirContextOperations group = ldapTemplate.searchForContext("", 
                "distinguishedName={0}", new Object[]{groupDn});
            
            String roleName = group.getStringAttribute("cn");
            authorities.add(new SimpleGrantedAuthority("ROLE_" + roleName.toUpperCase()));
            
            // Find parent groups
            String[] memberOf = group.getStringAttributes("memberOf");
            if (memberOf != null) {
                for (String parentGroupDn : memberOf) {
                    collectGroupHierarchy(parentGroupDn, authorities, processedGroups);
                }
            }
            
        } catch (Exception e) {
            // Log and continue with other groups
            logger.warn("Failed to process group: " + groupDn, e);
        }
    }
}

Role Mapping Configuration

@Component
public class MappedRoleAuthoritiesPopulator implements LdapAuthoritiesPopulator {
    
    private final DefaultLdapAuthoritiesPopulator delegate;
    private final Map<String, String> roleMapping;
    
    public MappedRoleAuthoritiesPopulator(ContextSource contextSource) {
        this.delegate = new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups");
        this.roleMapping = initializeRoleMapping();
    }
    
    private Map<String, String> initializeRoleMapping() {
        Map<String, String> mapping = new HashMap<>();
        mapping.put("LDAP_ADMINS", "ADMIN");
        mapping.put("LDAP_USERS", "USER");
        mapping.put("LDAP_MANAGERS", "MANAGER");
        mapping.put("LDAP_DEVELOPERS", "DEVELOPER");
        return mapping;
    }
    
    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(
            DirContextOperations userData, String username) {
        
        // Get authorities from delegate
        Collection<? extends GrantedAuthority> delegateAuthorities = 
            delegate.getGrantedAuthorities(userData, username);
        
        // Map to application-specific roles
        Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
        for (GrantedAuthority authority : delegateAuthorities) {
            String role = authority.getAuthority().replace("ROLE_", "");
            String mappedRole = roleMapping.getOrDefault(role, role);
            mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + mappedRole));
        }
        
        return mappedAuthorities;
    }
}

Integration with Authentication Provider

@Configuration
public class CompleteAuthenticationConfig {
    
    @Bean
    public LdapAuthenticationProvider ldapAuthenticationProvider() {
        // Configure authenticator
        BindAuthenticator authenticator = new BindAuthenticator(contextSource());
        authenticator.setUserSearch(userSearch());
        
        // Configure authorities populator
        DefaultLdapAuthoritiesPopulator authoritiesPopulator = 
            new DefaultLdapAuthoritiesPopulator(contextSource(), "ou=groups");
        authoritiesPopulator.setGroupSearchFilter("member={0}");
        authoritiesPopulator.setGroupRoleAttribute("cn");
        authoritiesPopulator.setRolePrefix("ROLE_");
        authoritiesPopulator.setDefaultRole("USER");
        
        // Create authentication provider
        LdapAuthenticationProvider provider = 
            new LdapAuthenticationProvider(authenticator, authoritiesPopulator);
        
        // Custom user details mapping
        provider.setUserDetailsContextMapper(customUserDetailsMapper());
        
        return provider;
    }
    
    @Bean
    public UserDetailsContextMapper customUserDetailsMapper() {
        LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
        mapper.setRolePrefix("ROLE_");
        return mapper;
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-security--spring-security-ldap

docs

authentication.md

authorities.md

context-management.md

embedded-server.md

index.md

json-serialization.md

password-policy.md

user-details.md

tile.json