The best choice depends on who is calling your API and whether you're building authentication yourself or delegating it.
For most new production systems in 2026, the recommendation is:
Use Spring Security 6 as the security framework, implement your API as an OAuth2 Resource Server that validates JWT access tokens, and use an external identity provider (IdP) to issue those tokens.
Think of these as complementary rather than competing options:
- Spring Security 6 → the security framework inside your application.
- OAuth2/OpenID Connect (OIDC) → the authentication/authorization protocols.
- JWT → a common token format.
- External identity provider → the service that authenticates users and issues JWTs.
Recommended architecture
Client (Web/Mobile)
│
▼
Identity Provider
(Auth0, Keycloak, Okta,
Azure AD, Cognito, etc.)
│
JWT Access Token
│
▼
Spring Boot API
(Spring Security Resource Server)
│
▼
Business Logic
Your API should generally verify tokens, not issue them.
Option 1: Spring Security + JWT only
Good for
- Internal services
- Small projects
- Learning
- Service-to-service authentication
Pros:
- Simple
- Fast
- Few moving parts
Cons:
- You become responsible for:
- login
- password storage
- MFA
- password reset
- account lockout
- email verification
- refresh tokens
- social login
This becomes a lot of security work.
Option 2: Spring Security + OAuth2 Resource Server + External IdP (recommended)
This is what many production systems use.
Spring Security validates JWTs issued by:
- Auth0
- Keycloak
- Okta
- Azure AD
- Amazon Cognito
Your application doesn't handle passwords.
Example configuration:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://your-idp.com/realms/myrealm
Then:
@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth -> oauth.jwt());
return http.build();
}
Spring automatically:
- validates signatures
- checks expiration
- validates issuer
- validates audience (if configured)
- builds the authenticated principal
Option 3: OAuth2 Authorization Server
Only build your own authorization server if you truly need one.
Examples:
- you're building an identity platform
- enterprise SSO
- multiple products
- custom login ecosystem
Otherwise:
Don't.
Running an authorization server correctly is difficult.
JWT vs OAuth2
These aren't alternatives.
OAuth2 is the protocol.
JWT is often the token format.
Example:
OAuth2
↓
Access Token
↓
JWT
You can absolutely have OAuth2 with JWT.
External identity provider advantages
Using an external IdP gives you:
- MFA
- Passkeys
- Social login
- Enterprise SSO
- Password policies
- Device management
- Token rotation
- Refresh token handling
- Account recovery
- Audit logs
- Security updates
without writing all that code yourself.
Best practices for Spring Security 6
Service-to-service APIs
For microservices, a common approach is:
Service A
│
Client Credentials Flow
│
JWT
│
Service B
Each service validates JWTs locally using the issuer's public keys, avoiding database lookups on every request.
Overall recommendation
| Scenario | Recommendation |
|---|
| Public REST API | Spring Security 6 + OAuth2 Resource Server + external IdP |
| Internal enterprise API | Same as above |
| Microservices | OAuth2 Client Credentials + JWT |
| Small side project | Spring Security + JWT may be sufficient |
| Building an identity platform | Spring Authorization Server or another dedicated authorization server |
For most production applications, Spring Security 6 configured as an OAuth2 Resource Server, validating JWT access tokens issued by a trusted external identity provider, offers the best balance of security, maintainability, and scalability. It lets your application focus on authorization and business logic while relying on a specialized identity service for authentication and credential management.