Spring Security 6 (Spring Boot 3.x) changed its API significantly. Here is a complete, working JWT authentication setup.
Why JWT for Frontend-Backend Separation
Session-based auth stores state on the server, making horizontal scaling painful. JWT is stateless and perfect for SPA + API architectures.
Key Changes in Spring Security 6
- WebSecurityConfigurerAdapter is gone. Use SecurityFilterChain beans instead.
- Lambda DSL is now the standard configuration style.
- Method security defaults to @PreAuthorize.
Step 1: JWT Utility Class
Using JJWT 0.12.x (not the old 0.9.x, the API is completely different):
The core methods are generateToken (builds a JWT with subject, issued-at, expiration, and signing key) and extractUsername (parses and verifies the token, then extracts the subject claim).
Step 2: Security Configuration
The SecurityFilterChain bean disables CSRF (not needed for stateless APIs), sets session creation policy to STATELESS, permits auth endpoints, requires authentication for admin endpoints, and adds the JWT filter before the UsernamePasswordAuthenticationFilter.
Security Hardening Checklist
- Token expiration: 24 hours max
- Passwords: BCrypt, never MD5 or SHA
- JWT secret: environment variable, never hardcoded
- HTTPS only in production
- Rate limit login attempts
- Validate token on every request, not just check for presence
Common Pitfalls
Using JJWT 0.9.x docs with 0.12.x - The API is completely different. Make sure your dependency version matches your code.
Forgetting STATELESS session policy - Without this, Spring creates sessions alongside JWT, defeating the purpose.
Not handling expired tokens gracefully - Return 401 with a clear message, not a 500 error.
Small team, big output. iDev builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. Free consultation.
Top comments (0)