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 Boot security starters integrate Spring Security and its ecosystem into your application. The base security starter configures authentication and authorization for servlet or reactive applications. Dedicated starters add OAuth 2.0 client flows, JWT-protected resource servers, a full Authorization Server, and enterprise SAML 2.0 federation — each one building on the previous layer.
All security starters depend on spring-boot-starter-security. You do not need to declare the base security starter separately when using any of the OAuth 2.0 or SAML starters.

spring-boot-starter-security

The foundational security starter. Auto-configures Spring Security with form login and HTTP Basic authentication, protects all endpoints by default, and generates a random password printed to the console on startup.Includes: spring-boot-starter · spring-boot-security · spring-aop
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
Override the generated credentials in application.properties for development:
application.properties
spring.security.user.name=admin
spring.security.user.password=changeme
spring.security.user.roles=ADMIN
Customize the security configuration by providing a SecurityFilterChain bean:
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults())
            .build();
    }
}
When to use: Any application that needs authentication and authorization. This is the starting point for all Spring Security configurations.
OAuth 2.0 and OpenID Connect (OIDC) client support. Enables @EnableOAuth2Client, auto-configures OAuth2AuthorizedClientManager, and provides login via external identity providers (Google, GitHub, Okta, Keycloak, etc.).Includes: spring-boot-starter · spring-boot-starter-security · spring-boot-security-oauth2-client · spring-security-oauth2-jose
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security-oauth2-client</artifactId>
</dependency>
Register a provider in application.properties:
application.properties
spring.security.oauth2.client.registration.github.client-id=your-client-id
spring.security.oauth2.client.registration.github.client-secret=your-client-secret

# Or use a custom OIDC provider
spring.security.oauth2.client.registration.my-idp.client-id=your-client-id
spring.security.oauth2.client.registration.my-idp.client-secret=your-client-secret
spring.security.oauth2.client.registration.my-idp.scope=openid,profile,email
spring.security.oauth2.client.provider.my-idp.issuer-uri=https://idp.example.com
When to use: Web applications where users log in through a third-party identity provider (social login, corporate SSO). Handles the authorization code flow, token storage, and token refresh automatically.
The older spring-boot-starter-oauth2-client artifact is deprecated. Use spring-boot-starter-security-oauth2-client for new projects.
Protects REST API endpoints by validating Bearer tokens (JWT or opaque). Auto-configures JWT decoding and BearerTokenAuthenticationFilter.Includes: spring-boot-starter · spring-boot-starter-security · spring-boot-security-oauth2-resource-server
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security-oauth2-resource-server</artifactId>
</dependency>
Minimal JWT resource server configuration:
application.properties
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://idp.example.com
@Configuration
@EnableWebSecurity
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .build();
    }
}
Extract custom claims from the JWT:
@RestController
@RequestMapping("/api")
public class ProfileController {

    @GetMapping("/me")
    public Map<String, Object> profile(JwtAuthenticationToken auth) {
        return Map.of(
            "sub",   auth.getToken().getSubject(),
            "email", auth.getToken().getClaimAsString("email")
        );
    }
}
When to use: Any REST API that accepts tokens issued by a separate authorization server. This is the most common security configuration for microservices behind an API gateway.
The older spring-boot-starter-oauth2-resource-server artifact is deprecated. Use spring-boot-starter-security-oauth2-resource-server for new projects.
Embeds a full Spring Authorization Server into your application — capable of issuing OAuth 2.0 and OIDC tokens using the authorization code, client credentials, and device authorization grant types.Includes: spring-boot-starter · spring-boot-starter-security · spring-boot-starter-webmvc · spring-boot-security-oauth2-authorization-server
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security-oauth2-authorization-server</artifactId>
</dependency>
Register a client in application.properties:
application.properties
spring.security.oauth2.authorizationserver.client.my-client.registration.client-id=my-client
spring.security.oauth2.authorizationserver.client.my-client.registration.client-secret={noop}secret
spring.security.oauth2.authorizationserver.client.my-client.registration.authorization-grant-types=authorization_code,refresh_token
spring.security.oauth2.authorizationserver.client.my-client.registration.redirect-uris=https://app.example.com/callback
spring.security.oauth2.authorizationserver.client.my-client.registration.scopes=openid,profile
When to use: Building a centralized identity provider for your own ecosystem of services, or when you need a self-hosted OIDC-compliant token issuer.
The older spring-boot-starter-oauth2-authorization-server artifact is deprecated. Use spring-boot-starter-security-oauth2-authorization-server for new projects.
SAML 2.0 authentication support, enabling your application to act as a SAML Service Provider (SP) and authenticate users through enterprise Identity Providers (IdPs) like Okta, ADFS, or Shibboleth.Includes: spring-boot-starter · spring-boot-starter-security · spring-boot-security-saml2
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security-saml2</artifactId>
</dependency>
Configure your SAML IdP via metadata URL:
application.properties
spring.security.saml2.relyingparty.registration.my-idp.assertingparty.metadata-uri=https://idp.example.com/saml/metadata
spring.security.saml2.relyingparty.registration.my-idp.entity-id=https://my-app.example.com
spring.security.saml2.relyingparty.registration.my-idp.acs.location=https://my-app.example.com/login/saml2/sso
When to use: Enterprise SSO integrations where the identity provider speaks SAML 2.0 — common in regulated industries and corporate environments.

Testing security

spring-boot-starter-security-test

Test utilities from Spring Security: @WithMockUser, @WithUserDetails, SecurityMockMvcRequestPostProcessors, and WebTestClientSecurityConfigurer. Includes: spring-boot-starter-security · spring-boot-starter-test · spring-boot-security-test
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security-test</artifactId>
    <scope>test</scope>
</dependency>

@WithMockUser

Inject a mock authenticated user into the security context without hitting an actual identity provider:
@SpringBootTest
@AutoConfigureMockMvc
class ProfileControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(username = "alice", roles = {"USER"})
    void getProfile_returnsUserData() throws Exception {
        mockMvc.perform(get("/api/me"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.username").value("alice"));
    }

    @Test
    void getProfile_unauthenticated_returns401() throws Exception {
        mockMvc.perform(get("/api/me"))
               .andExpect(status().isUnauthorized());
    }
}

SecurityMockMvcRequestPostProcessors

Apply security context to individual requests without a class-level annotation:
@Test
void adminEndpoint_withAdminUser_returns200() throws Exception {
    mockMvc.perform(get("/admin/stats")
               .with(user("bob").roles("ADMIN")))
           .andExpect(status().isOk());
}

@Test
void adminEndpoint_withRegularUser_returns403() throws Exception {
    mockMvc.perform(get("/admin/stats")
               .with(user("carol").roles("USER")))
           .andExpect(status().isForbidden());
}

Testing JWT resource servers

Use SecurityMockMvcRequestPostProcessors.jwt() to pass a synthetic JWT without a real token issuer:
@Test
void securedEndpoint_withJwt_returns200() throws Exception {
    mockMvc.perform(get("/api/orders")
               .with(jwt().jwt(token -> token
                   .subject("user-123")
                   .claim("scope", "read:orders"))))
           .andExpect(status().isOk());
}

Testing with WebTestClient (reactive)

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class ReactiveApiTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void securedRoute_withMockUser_returns200() {
        webTestClient
            .mutateWith(mockUser().roles("USER"))
            .get().uri("/api/me")
            .exchange()
            .expectStatus().isOk();
    }
}
For OAuth 2.0 resource server tests, use mockJwt() from SecurityMockMvcRequestPostProcessors (servlet) or mockJwt() from SecurityMockServerConfigurers (reactive) instead of jwt(). Both let you control the claims without spinning up a token issuer.

Build docs developers (and LLMs) love