This project demonstrates the evolution of Spring Security in a Spring Boot API, from basic route protection to a fully stateless authentication flow using JWT.
The goal of this project is to explore how authentication and authorization work in practice, step by step:
- Route protection with Spring Security
- Custom authentication (register + login)
- Stateless authentication and authorization with JWT
- Java 21
- Spring Boot
- Spring Security
- JWT (JJWT)
- H2 Database
- Lombok
/auth/public→ public endpoint/auth/private→ protected endpoint
Instead of relying on Spring Security’s default login flow, this project implements custom endpoints for authentication:
/auth/register→ user registration/auth/login→ user authentication
Passwords are securely stored using BCrypt.
After successful login:
- credentials are validated
- a JWT token is generated
- the client must send the token in subsequent requests
Example:
Authorization: Bearer <token>The token includes:
- user identity (
subject) - user id
- user role
- expiration time
The project includes a custom JwtAuthenticationFilter responsible for:
- intercepting requests
- extracting the JWT from the request header
- validating the token
- extracting claims
- authenticating the user in Spring Security’s
SecurityContext
The API supports authorization based on user roles.
Examples:
/auth/admin→ requiresOWNER/auth/client→ requiresOWNERorCLIENT
Implemented using:
hasRole(...)hasAnyRole(...)
Custom security handlers were implemented to standardize authentication and authorization errors:
Returned when:
- token is missing
- token is invalid
Handled by:
CustomAuthenticationEntryPoint
Returned when:
- the authenticated user does not have permission to access a resource
Handled by:
CustomAccessDeniedHandler
The project also includes:
GlobalExceptionHandler- standardized API error responses using
ProblemDetail
Validation errors return structured responses containing invalid fields and messages.
Spring Security is configured to:
- disable
formLogin - disable
httpBasic - use stateless session management
- allow public authentication routes
- protect private routes
- authenticate requests through JWT
The application now supports:
- custom authentication flow
- stateless JWT authentication
- token validation
- claims extraction
- role-based authorization
- standardized error handling
Potential future improvements:
- refresh token flow
- persistent database
- UserDetailsService integration
- token revocation / blacklist
- integration and security tests
This project is part of a learning series about Spring Security and JWT.
- Post I → Route protection with Spring Security
- Post II → Custom authentication (register + login)
- Post III → JWT authentication and authorization
- LinkedIn: Lucas Oliveira