Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/spring-projects/spring-boot/llms.txt

Use this file to discover all available pages before exploring further.

Spring Security integrates with Spring Boot through a single starter that activates comprehensive protection by default. When spring-boot-starter-security is on the classpath, every endpoint in your application — including Spring Boot’s own /error path and Actuator endpoints — is secured automatically, requiring authentication before any request succeeds.

Default security behavior

The default UserDetailsService has a single user. The username is user and the password is randomly generated and printed at WARN level when the application starts:
Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35

This generated password is for development use only. Your security configuration must be updated before running your application in production.
You can override the default credentials using properties:
application.yaml
spring:
  security:
    user:
      name: "admin"
      password: "changeme"
Never use the auto-generated password or hardcoded credentials in production. Configure a real UserDetailsService or an external identity provider before deploying.
The default security provides:
  • A UserDetailsService (or ReactiveUserDetailsService for WebFlux) with an in-memory store and a single user
  • Form-based login or HTTP Basic security depending on the Accept header in the request
  • A DefaultAuthenticationEventPublisher for publishing authentication events

MVC security configuration

To replace the default behavior, add a SecurityFilterChain bean. Adding this bean disables Spring Boot’s default web security configuration while leaving the UserDetailsService configuration in place.
MySecurityConfiguration.java
@Configuration
public class MySecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults())
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}
Spring Boot provides convenience matchers to simplify access rules:
  • EndpointRequest — creates a RequestMatcher based on the management.endpoints.web.base-path property
  • PathRequest — creates a RequestMatcher for commonly used resource locations
To also switch off the UserDetailsService configuration, add a bean of type UserDetailsService, AuthenticationProvider, or AuthenticationManager.
The auto-configuration of a UserDetailsService backs off automatically when any of spring-security-oauth2-client, spring-security-oauth2-resource-server, or spring-security-saml2-service-provider is on the classpath.

WebFlux security

For WebFlux applications, add spring-boot-starter-security and configure a SecurityWebFilterChain bean:
MyWebFluxSecurityConfiguration.java
@Configuration
public class MyWebFluxSecurityConfiguration {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange(exchanges -> exchanges
                .pathMatchers("/public/**").permitAll()
                .anyExchange().authenticated()
            )
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}

Authentication flows

HTTP Basic and form-based login are enabled by Spring Boot’s default auto-configuration. To customize, define your own SecurityFilterChain with explicit httpBasic() or formLogin() configuration.Configure a custom UserDetailsService to load users from a database:
MyUserDetailsService.java
@Service
public class MyUserDetailsService implements UserDetailsService {

    private final UserRepository repository;

    public MyUserDetailsService(UserRepository repository) {
        this.repository = repository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return repository.findByUsername(username)
            .map(user -> User.withUsername(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRoles())
                .build())
            .orElseThrow(() -> new UsernameNotFoundException(username));
    }
}
Add spring-boot-starter-oauth2-client and configure your OAuth2 provider in application.yaml. Spring Boot includes pre-built support for common providers (Google, GitHub, Okta):
application.yaml
spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: "your-client-id"
            client-secret: "your-client-secret"
            scope:
              - openid
              - profile
              - email
Add OAuth2 login to your security configuration:
MyOAuth2SecurityConfiguration.java
@Configuration
public class MyOAuth2SecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .oauth2Login(Customizer.withDefaults());
        return http.build();
    }
}
Add spring-boot-starter-oauth2-resource-server to protect your API with JWT bearer tokens. Configure the issuer URI of your authorization server:
application.yaml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: "https://auth.example.com"
Configure the security filter chain:
MyResourceServerConfiguration.java
@Configuration
public class MyResourceServerConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/**").authenticated()
                .anyRequest().permitAll()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(Customizer.withDefaults())
            );
        return http.build();
    }
}
Spring Boot auto-configures a JwtDecoder bean using the issuer URI to discover the JWKS endpoint.
SAML v2.0 is a widely adopted framework for exchanging security information between business partners. Add spring-security-saml2-service-provider and configure your identity provider:
application.yaml
spring:
  security:
    saml2:
      relyingparty:
        registration:
          my-idp:
            identityprovider:
              metadata-uri: "https://idp.example.com/metadata"
              verification:
                credentials:
                  - certificate-location: "classpath:saml/idp.crt"
Spring Boot auto-configures a RelyingPartyRegistrationRepository and the SAML2 login filter chain when the dependency is present.
Add method-level security using @EnableMethodSecurity on a @Configuration class:
MyMethodSecurityConfiguration.java
@Configuration
@EnableMethodSecurity
public class MyMethodSecurityConfiguration {
}
Secure service methods with standard annotations:
MyService.java
@Service
public class MyService {

    @PreAuthorize("hasRole('ADMIN')")
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @PostAuthorize("returnObject.owner == authentication.name")
    public Document getDocument(Long id) {
        return documentRepository.findById(id).orElseThrow();
    }
}

H2 console in a secured application

The H2 console uses frames and does not implement CSRF protection. In a secured application you must configure Spring Security to allow access:
DevProfileSecurityConfiguration.java
@Profile("dev")
@Configuration
public class DevProfileSecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(PathRequest.toH2Console()).permitAll()
                .anyRequest().authenticated()
            )
            .csrf(csrf -> csrf
                .ignoringRequestMatchers(PathRequest.toH2Console())
            )
            .headers(headers -> headers
                .frameOptions(frame -> frame.sameOrigin())
            );
        return http.build();
    }
}
The H2 console is only intended for use during development. In production, disabling CSRF protection or allowing frames for a website may create severe security risks.

Build docs developers (and LLMs) love