A production-ready RESTful API for user authentication and authorization using JWT tokens and role-based access control (RBAC) built with Spring Boot 3, Spring Security 6, and PostgreSQL.
- β User Registration & Login - Secure user account creation and authentication
- β JWT Token Authentication - Stateless authentication using JSON Web Tokens
- β Role-Based Access Control - USER and ADMIN roles with method-level security
- β Password Hashing - BCrypt password encryption
- β Token Validation - Automatic JWT validation on protected endpoints
- β Error Handling - Standardized error responses
- β API Documentation - Interactive Swagger UI documentation
- β PostgreSQL Database - Persistent data storage with JPA/Hibernate
- Java 17
- Spring Boot 3.2.1
- Spring Security 6
- Spring Data JPA
- PostgreSQL - Database
- JSON Web Tokens (JWT) - Authentication
- Lombok - Boilerplate reduction
- SpringDoc OpenAPI 3 - API documentation
- Maven - Build tool
- Java 17 or higher
- PostgreSQL 12 or higher
- Maven 3.6+
- Git
git clone <repository-url>
cd springboot_Auth_jwt_rbacCreate a PostgreSQL database:
# Using psql
psql -U postgres
CREATE DATABASE spring_auth;
\qOr using the command line:
createdb -U postgres spring_authEdit src/main/resources/application.properties if you need to change database credentials:
spring.datasource.url=jdbc:postgresql://localhost:5432/spring_auth
spring.datasource.username=postgres
spring.datasource.password=rootmvn clean installmvn spring-boot:runOr run the JAR file:
java -jar target/jwt-auth-rbac-0.0.1-SNAPSHOT.jarThe application will start on http://localhost:8080
Access the interactive API documentation at:
http://localhost:8080/swagger-ui.html
Get the OpenAPI JSON specification at:
http://localhost:8080/v3/api-docs
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Register a new user |
| POST | /api/auth/login |
Login user and get JWT token |
| Method | Endpoint | Description | Required Role |
|---|---|---|---|
| GET | /api/users/me |
Get current user profile | USER, ADMIN |
| GET | /api/users |
Get all users | ADMIN |
| GET | /api/users/{id} |
Get user by ID | ADMIN |
| DELETE | /api/users/{id} |
Delete user | ADMIN |
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"fullName": "John Doe"
}'Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"email": "user@example.com",
"fullName": "John Doe",
"role": "USER",
"expiresIn": 3600000
}curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",mvn spring-boot:run
"password": "password123"
}'curl -X GET http://localhost:8080/api/users/me \
-H "Authorization: Bearer YOUR_JWT_TOKEN"curl -X GET http://localhost:8080/api/users/mespringboot_Auth_jwt_rbac/
βββ src/
β βββ main/
β β βββ java/com/auth/jwt/
β β β βββ config/ # Configuration classes
β β β β βββ ApplicationConfig.java
β β β β βββ OpenApiConfig.java
β β β β βββ SecurityConfig.java
β β β βββ controller/ # REST controllers
β β β β βββ AuthenticationController.java
β β β β βββ UserController.java
β β β βββ dto/ # Data Transfer Objects
β β β β βββ AuthResponse.java
β β β β βββ ErrorResponse.java
β β β β βββ LoginRequest.java
β β β β βββ RegisterRequest.java
β β β β βββ UserResponse.java
β β β βββ entity/ # JPA entities
β β β β βββ Role.java
β β β β βββ User.java
β β β βββ exception/ # Custom exceptions
β β β β βββ GlobalExceptionHandler.java
β β β β βββ InvalidCredentialsException.java
β β β β βββ ResourceNotFoundException.java
β β β β βββ UnauthorizedAccessException.java
β β β β βββ UserAlreadyExistsException.java
β β β βββ filter/ # Security filters
β β β β βββ JwtAuthenticationFilter.java
β β β βββ repository/ # Data repositories
β β β β βββ UserRepository.java
β β β βββ security/ # Security utilities
β β β β βββ CustomUserDetailsService.java
β β β β βββ JwtUtil.java
β β β βββ service/ # Business logic
β β β β βββ AuthenticationService.java
β β β β βββ UserService.java
β β β βββ JwtAuthApplication.java
β β βββ resources/
β β βββ application.properties
β βββ test/ # Test files
βββ pom.xml
βββ README.md
- Password Hashing - All passwords are hashed using BCrypt before storage
- JWT Token Security - Tokens are signed with a secret key and validated on each request
- Token Expiration - Tokens expire after 1 hour (configurable)
- Stateless Authentication - No server-side session storage
- Role-Based Authorization - Method-level security with
@PreAuthorize - Input Validation - Request validation using Bean Validation
- Error Security - Sensitive information is not leaked in error messages
- Change JWT Secret - Store in environment variables or secrets manager
- Use HTTPS - Enable SSL/TLS for all communications
- Database Security - Use strong database passwords and restrict access
- Environment Variables - Externalize all sensitive configuration
- CORS Configuration - Configure CORS policies for your frontend domain
- Rate Limiting - Implement rate limiting to prevent brute force attacks
- Logging & Monitoring - Add comprehensive logging and monitoring
- Registration/Login β User provides credentials
- Password Verification β Password is verified using BCrypt
- JWT Generation β Server generates JWT token with user info
- Token Response β Token is sent to client
- Client Storage β Client stores token (localStorage/sessionStorage)
- Protected Requests β Client sends token in Authorization header
- Token Validation β Server validates token on each request
- Access Granted β User accesses protected resources
Edit src/main/resources/application.properties:
# JWT secret key (Base64 encoded) - CHANGE IN PRODUCTION!
jwt.secret=404E635266556A586E3272357538782F413F4428472B4B6250645367566B5970
# JWT expiration time in milliseconds (1 hour = 3600000 ms)
jwt.expiration=3600000spring.datasource.url=jdbc:postgresql://localhost:5432/todo_db
spring.datasource.username=postgres
spring.datasource.password=rootThe system assigns the USER role by default. To create an admin user:
- Register a new user via API
- Manually update the role in the database:
UPDATE users SET role = 'ADMIN' WHERE email = 'admin@example.com';Or use a database client to manually set the role to ADMIN.
| Column | Type | Constraints |
|---|---|---|
| id | BIGSERIAL | PRIMARY KEY |
| VARCHAR(100) | UNIQUE, NOT NULL | |
| password | VARCHAR(255) | NOT NULL |
| full_name | VARCHAR(100) | NOT NULL |
| role | VARCHAR(20) | NOT NULL |
| created_at | TIMESTAMP | NOT NULL |
| updated_at | TIMESTAMP | NOT NULL |
Error: Connection refused
Solution: Ensure PostgreSQL is running and credentials are correct.
Error: JWT token has expired
Solution: Login again to get a new token.
Error: Access denied
Solution: Ensure you have the required role (ADMIN) for the endpoint.
This project is licensed under the MIT License.
Spring Boot JWT Auth Team
Contributions are welcome! Please feel free to submit a Pull Request.
Happy Coding! π