Spring Security Configuration: From Default to Advanced Setup

This document has been created to answer the question of what is the best way to understand Spring Security and customise configuration on demand. 

So we will start with the default configuration first and move to the customisation.


1. Default Spring Security Setup (Basic)

Description

A minimal setup relying on Spring Boot’s auto-configuration. Ideal for quick prototypes or standard username/password-based logins.

Key Characteristics

  • Uses DaoAuthenticationProvider automatically

  • Relies on AuthenticationConfiguration — Spring Boot’s default internal configuration class — to create the AuthenticationManager

  • This class becomes the first point of customisation if you want to override the default authentication behaviour

  • Minimal manual setup required

Example

@Configuration
public class ApplicationConfiguration {

    @Bean
    public UserDetailsService userDetailsService(UserRepository userRepository) {
        return username -> userRepository.findByEmail(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationProvider authenticationProvider(UserDetailsService userDetailsService) {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
}

🛠️ 2. Advanced Security Setup (Custom)

Description

A fully customizable setup allowing for token-based authentication, path-specific security chains, and integration of filters like JWT validation.

Key Characteristics

  • Manually builds AuthenticationManager from HttpSecurity

  • Integrates custom AuthenticationProvider

  • Adds JwtAuthFilter before standard filters

  • Uses SecurityFilterChain with securityMatcher()

  • The HttpSecurity object used to build AuthenticationManager is the same instance being configured in the SecurityFilterChain

Example: AdventureTube Auth Service

@Configuration
@EnableWebSecurity
@AllArgsConstructor
public class AuthServiceConfig {

    private final CustomUserDetailService customUserDetailService;
    private final JwtAuthFilter jwtAuthFilter;

    @Bean
    @Order(1)
    public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .securityMatcher("/auth/**")
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(SecurityConstants.OPEN_ENDPOINTS).permitAll()
                .anyRequest().hasRole("ADMIN")
            )
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    @Bean
    public AuthenticationManager customAuthenticationManager(HttpSecurity http) throws Exception {
        // This http instance is the same as used in SecurityFilterChain
        AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class);
        builder.authenticationProvider(customAuthenticationProvider());
        return builder.build();
    }

    @Bean
    public CustomAuthenticationProvider customAuthenticationProvider() {
        return new CustomAuthenticationProvider(customUserDetailService, passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Summary Comparison

FeatureDefault SetupCustom Setup
AuthenticationManagerAuto-wired via AuthenticationConfiguration (default class)Built manually using HttpSecurity
Provider TypeDaoAuthenticationProviderCustomAuthenticationProvider
FlexibilityLowHigh
Filter ControlMinimalFull control (e.g., JWT, token validation)
Path-Specific ConfigNoYes (securityMatcher("/auth/**"))
Reuses HttpSecurityNot applicableYes (same HttpSecurity used for filter chain and manager)
Recommended ForSimple login flowsToken-based, microservice, advanced setups

This transition from basic to advanced Spring Security configuration empowers developers to scale from rapid prototyping to secure, production-ready systems with fine-grained control.

Leave a Comment

Your email address will not be published. Required fields are marked *