Spring Security configuration module providing comprehensive declarative security configuration capabilities for Spring applications
—
Spring Security Config provides comprehensive authentication configuration capabilities through builders and configurers that support various authentication mechanisms including in-memory, JDBC, LDAP, and custom authentication providers.
The primary builder for configuring AuthenticationManager instances with multiple authentication providers.
public class AuthenticationManagerBuilder
extends AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>
implements ProviderManagerBuilder<AuthenticationManagerBuilder> {
// User Details Services Configuration
public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception;
public JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcAuthentication() throws Exception;
public LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> ldapAuthentication() throws Exception;
// Custom User Details Service
public DaoAuthenticationConfigurer<AuthenticationManagerBuilder, InMemoryUserDetailsManager> userDetailsService(UserDetailsService userDetailsService) throws Exception;
// Custom Authentication Provider
public AuthenticationManagerBuilder authenticationProvider(AuthenticationProvider authenticationProvider);
// Parent Authentication Manager
public AuthenticationManagerBuilder parentAuthenticationManager(AuthenticationManager authenticationManager);
// Authentication Event Publisher
public AuthenticationManagerBuilder authenticationEventPublisher(AuthenticationEventPublisher eventPublisher);
// Security Configuration
public AuthenticationManagerBuilder eraseCredentials(boolean eraseCredentials);
// Build Configuration
public AuthenticationManager build() throws Exception;
}Usage Example:
@Bean
public AuthenticationManager authenticationManager(
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder)
.and()
.authenticationProvider(customAuthenticationProvider())
.parentAuthenticationManager(globalAuthenticationManager())
.build();
}Configuration for in-memory user storage and authentication.
public class InMemoryUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B>>
extends UserDetailsManagerConfigurer<B, InMemoryUserDetailsManagerConfigurer<B>> {
// User Creation
public UserDetailsBuilder withUser(String username);
public InMemoryUserDetailsManagerConfigurer<B> withUser(UserDetails userDetails);
// Password Encoder
public InMemoryUserDetailsManagerConfigurer<B> passwordEncoder(PasswordEncoder passwordEncoder);
// User Details Builder
public final class UserDetailsBuilder {
public UserDetailsBuilder password(String password);
public UserDetailsBuilder roles(String... roles);
public UserDetailsBuilder authorities(String... authorities);
public UserDetailsBuilder authorities(GrantedAuthority... authorities);
public UserDetailsBuilder accountExpired(boolean accountExpired);
public UserDetailsBuilder accountLocked(boolean accountLocked);
public UserDetailsBuilder credentialsExpired(boolean credentialsExpired);
public UserDetailsBuilder disabled(boolean disabled);
public UserDetails build();
public InMemoryUserDetailsManagerConfigurer<B> and();
}
}Usage Example:
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.inMemoryAuthentication()
.passwordEncoder(passwordEncoder())
.withUser("admin")
.password("admin123")
.roles("ADMIN", "USER")
.and()
.withUser("user")
.password("user123")
.roles("USER")
.accountExpired(false)
.credentialsExpired(false)
.disabled(false)
.accountLocked(false)
.and()
.and()
.build();
}Configuration for JDBC-based user storage and authentication.
public class JdbcUserDetailsManagerConfigurer<B extends ProviderManagerBuilder<B>>
extends UserDetailsServiceConfigurer<B, JdbcUserDetailsManagerConfigurer<B>, JdbcUserDetailsManager> {
// Data Source Configuration
public JdbcUserDetailsManagerConfigurer<B> dataSource(DataSource dataSource);
// Query Configuration
public JdbcUserDetailsManagerConfigurer<B> usersByUsernameQuery(String query);
public JdbcUserDetailsManagerConfigurer<B> authoritiesByUsernameQuery(String query);
public JdbcUserDetailsManagerConfigurer<B> groupAuthoritiesByUsername(String query);
// Role and Authority Configuration
public JdbcUserDetailsManagerConfigurer<B> rolePrefix(String rolePrefix);
public JdbcUserDetailsManagerConfigurer<B> usernameParameter(String usernameParameter);
// Password Encoder
public JdbcUserDetailsManagerConfigurer<B> passwordEncoder(PasswordEncoder passwordEncoder);
// User Details Service
public JdbcUserDetailsManagerConfigurer<B> userDetailsService(JdbcUserDetailsManager userDetailsService);
// User Creation
public UserDetailsBuilder withUser(String username);
public JdbcUserDetailsManagerConfigurer<B> withUser(UserDetails user);
// Default User Creation
public JdbcUserDetailsManagerConfigurer<B> withDefaultSchema();
}Usage Example:
@Bean
public AuthenticationManager authenticationManager(DataSource dataSource) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?")
.authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?")
.rolePrefix("ROLE_")
.withDefaultSchema()
.withUser("admin")
.password("admin123")
.roles("ADMIN")
.and()
.and()
.build();
}Configuration for DAO-based authentication with custom UserDetailsService.
public class DaoAuthenticationConfigurer<B extends ProviderManagerBuilder<B>, U extends UserDetailsService>
extends UserDetailsServiceConfigurer<B, DaoAuthenticationConfigurer<B, U>, U> {
// User Details Service
public DaoAuthenticationConfigurer<B, U> userDetailsService(U userDetailsService);
// Password Encoder
public DaoAuthenticationConfigurer<B, U> passwordEncoder(PasswordEncoder passwordEncoder);
// User Details Password Service
public DaoAuthenticationConfigurer<B, U> userDetailsPasswordService(UserDetailsPasswordService userDetailsPasswordService);
}Usage Example:
@Bean
public AuthenticationManager authenticationManager(
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder)
.userDetailsPasswordService(userDetailsPasswordService())
.and()
.build();
}Configuration for LDAP-based authentication.
public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuilder<B>>
extends AbstractLdapAuthenticationProviderConfigurer<B, LdapAuthenticationProviderConfigurer<B>> {
// Context Source Configuration
public LdapAuthenticationProviderConfigurer<B> contextSource(BaseLdapPathContextSource contextSource);
// User Search Configuration
public LdapAuthenticationProviderConfigurer<B> userSearchBase(String userSearchBase);
public LdapAuthenticationProviderConfigurer<B> userSearchFilter(String userSearchFilter);
public LdapAuthenticationProviderConfigurer<B> userDnPatterns(String... userDnPatterns);
// Group Search Configuration
public LdapAuthenticationProviderConfigurer<B> groupSearchBase(String groupSearchBase);
public LdapAuthenticationProviderConfigurer<B> groupSearchFilter(String groupSearchFilter);
public LdapAuthenticationProviderConfigurer<B> groupRoleAttribute(String groupRoleAttribute);
// Authentication Strategy Configuration
public PasswordComparisonConfigurer<LdapAuthenticationProviderConfigurer<B>> passwordCompare();
public BindAuthenticatorConfigurer<LdapAuthenticationProviderConfigurer<B>> bindAuthentication();
// Role and Authority Configuration
public LdapAuthenticationProviderConfigurer<B> rolePrefix(String rolePrefix);
public LdapAuthenticationProviderConfigurer<B> userDetailsContextMapper(UserDetailsContextMapper userDetailsContextMapper);
// Nested Configuration Classes
public final class PasswordComparisonConfigurer<T> {
public PasswordComparisonConfigurer<T> passwordEncoder(PasswordEncoder passwordEncoder);
public PasswordComparisonConfigurer<T> passwordAttribute(String passwordAttribute);
public T and();
}
public final class BindAuthenticatorConfigurer<T> {
public T and();
}
}Usage Example:
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.userSearchBase("ou=people")
.userSearchFilter("(uid={0})")
.groupSearchBase("ou=groups")
.groupSearchFilter("(uniqueMember={0})")
.groupRoleAttribute("cn")
.rolePrefix("ROLE_")
.contextSource(contextSource())
.passwordCompare()
.passwordEncoder(passwordEncoder())
.passwordAttribute("userPassword")
.and()
.and()
.build();
}
@Bean
public BaseLdapPathContextSource contextSource() {
DefaultSpringSecurityContextSource contextSource =
new DefaultSpringSecurityContextSource("ldap://localhost:389/dc=example,dc=com");
contextSource.setUserDn("cn=admin,dc=example,dc=com");
contextSource.setPassword("admin");
return contextSource;
}Global authentication configuration providing AuthenticationManager beans.
@Configuration
@Import(ObjectPostProcessorConfiguration.class)
public class AuthenticationConfiguration {
// Authentication Manager Bean
@Bean
public AuthenticationManager authenticationManager() throws Exception;
// Authentication Manager Builder
@Bean
public AuthenticationManagerBuilder authenticationManagerBuilder(
ObjectPostProcessor<Object> objectPostProcessor,
ApplicationContext context);
// Global Authentication Configurer Adapter
@Bean
public static GlobalAuthenticationConfigurerAdapter enableGlobalAuthenticationAutowiredConfigurer(
ApplicationContext context);
// Authentication Event Publisher
@Bean
public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher publisher);
}Base class for configuring global authentication.
public abstract class GlobalAuthenticationConfigurerAdapter implements SecurityConfigurer<AuthenticationManager, AuthenticationManagerBuilder> {
public void init(AuthenticationManagerBuilder auth) throws Exception {}
public void configure(AuthenticationManagerBuilder auth) throws Exception {}
}Usage Example:
@Configuration
public class CustomAuthenticationConfig extends GlobalAuthenticationConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
}Implement custom authentication logic by creating AuthenticationProvider implementations.
public interface AuthenticationProvider {
/**
* Performs authentication with the same contract as AuthenticationManager.
* @param authentication the authentication request object
* @return a fully authenticated object including credentials
* @throws AuthenticationException if authentication fails
*/
Authentication authenticate(Authentication authentication) throws AuthenticationException;
/**
* Returns true if this AuthenticationProvider supports the indicated
* Authentication object.
* @param authentication the Authentication class
* @return true if the implementation can process the Authentication class
*/
boolean supports(Class<?> authentication);
}Custom Provider Example:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (passwordEncoder.matches(password, userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(
userDetails, password, userDetails.getAuthorities());
} else {
throw new BadCredentialsException("Authentication failed");
}
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
// Configuration
@Bean
public AuthenticationManager authenticationManager(
CustomAuthenticationProvider customProvider) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.authenticationProvider(customProvider)
.build();
}Configure password encoding for secure credential storage.
public interface PasswordEncoder {
/**
* Encode the raw password.
* @param rawPassword the raw password to encode
* @return the encoded password
*/
String encode(CharSequence rawPassword);
/**
* Verify the encoded password obtained from storage matches the submitted raw password.
* @param rawPassword the raw password to verify
* @param encodedPassword the encoded password from storage
* @return true if the raw password matches the encoded password
*/
boolean matches(CharSequence rawPassword, String encodedPassword);
/**
* Returns true if the encoded password should be encoded again for better security.
* @param encodedPassword the encoded password to check
* @return true if the encoded password should be encoded again
*/
default boolean upgradeEncoding(String encodedPassword) {
return false;
}
}Password Encoder Configuration:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Bean
public AuthenticationManager authenticationManager(
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder)
.and()
.build();
}Configure authentication event publishing for monitoring and auditing.
public interface AuthenticationEventPublisher {
/**
* Publish a successful authentication event.
* @param authentication the successful authentication
*/
void publishAuthenticationSuccess(Authentication authentication);
/**
* Publish an authentication failure event.
* @param exception the authentication exception
* @param authentication the failed authentication attempt
*/
void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication);
}Event Publisher Configuration:
@Bean
public AuthenticationEventPublisher authenticationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
return new DefaultAuthenticationEventPublisher(applicationEventPublisher);
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationEventPublisher eventPublisher) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.authenticationEventPublisher(eventPublisher)
.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder())
.and()
.build();
}
@EventListener
public void handleAuthenticationSuccess(AuthenticationSuccessEvent event) {
log.info("Authentication success for user: {}", event.getAuthentication().getName());
}
@EventListener
public void handleAuthenticationFailure(AbstractAuthenticationFailureEvent event) {
log.warn("Authentication failure: {}", event.getException().getMessage());
}Configure multiple authentication providers for different authentication strategies:
@Bean
public AuthenticationManager authenticationManager(
UserDetailsService userDetailsService,
LdapAuthenticationProvider ldapProvider,
CustomAuthenticationProvider customProvider) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.authenticationProvider(ldapProvider)
.authenticationProvider(customProvider)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder())
.and()
.build();
}Configure parent-child authentication manager relationships:
@Bean
public AuthenticationManager parentAuthenticationManager() throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.inMemoryAuthentication()
.withUser("global-admin")
.password("global-password")
.roles("GLOBAL_ADMIN")
.and()
.build();
}
@Bean
public AuthenticationManager childAuthenticationManager(
AuthenticationManager parentAuthenticationManager) throws Exception {
return new AuthenticationManagerBuilder(objectPostProcessor)
.parentAuthenticationManager(parentAuthenticationManager)
.userDetailsService(localUserDetailsService())
.passwordEncoder(passwordEncoder())
.and()
.build();
}Integrate custom user storage and retrieval logic:
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));
return User.builder()
.username(user.getUsername())
.password(user.getPassword())
.authorities(user.getAuthorities())
.accountExpired(!user.isAccountNonExpired())
.accountLocked(!user.isAccountNonLocked())
.credentialsExpired(!user.isCredentialsNonExpired())
.disabled(!user.isEnabled())
.build();
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-security--spring-security-config