This project demonstrates a secure RESTful API built with Spring Boot and Spring Security, implementing JWT (JSON Web Token) authentication.
It is a complete CRUD (Create, Read, Update, Delete) application with role-based authorization, designed to showcase modern security practices in Java backend development.
✅ Robust Spring Security Implementation
✅ JWT Authentication with Bearer tokens
✅ Role-based authorization (👤 USER, 🛠 MODERATOR, 👑 ADMIN)
✅ Secure password storage with 🔑 BCrypt hashing
✅ Token validation with expiration (⏳ 10 minutes)
✅ Custom security filters for JWT processing
✅ Custom authentication provider integration
✅ Advanced authorization logic with 🔍 PermissionEvaluator
for fine-grained access control
- Java 21 – main programming language
- Spring Boot – backend application framework
- Spring Security – authentication and authorization
- JWT (JSON Web Token) – token-based authentication
- JPA (Hibernate) – object-relational mapping
- PostgreSQL – relational database
- Flyway – database schema versioning and migrations
- Maven – dependency management and build automation
- JUnit 5 + MockMvc – unit and integration testing
- Mockito – mocking dependencies in tests
- Docker + Docker Compose – containerization and database setup
- REST API – client-server communication architecture
- JwtFilter – Validates tokens on each request
- JWTCustomUsernamePasswordAuthenticationFilter – Handles login and token generation
- JwtAuthenticationProvider – Validates JWT tokens
- CustomUserDetailsService – Integrates with Spring Security's authentication flow
- ProjectConfig – Central security configuration
- CustomPermissionEvaluator – Enables fine-grained, method-level authorization logic based on permissions
The UserUpdatePermissionEvaluator
implements sophisticated business rules for user updates:
Current Role | Target User | Action | Result |
---|---|---|---|
ADMIN | Any user | Update | ✅ Allowed |
MODERATOR | Regular user | Update | ✅ Allowed |
MODERATOR | ADMIN user | Update | ❌ Blocked (AdminUpdateForbiddenException ) |
MODERATOR | Any user | Assign ADMIN role | ❌ Blocked (AdminRoleAssignmentException ) |
USER | Any user | Update | ❌ Blocked (AccessDeniedException ) |
- ADMIN has unrestricted update privileges
- MODERATOR can only update non-admin users
- MODERATOR cannot promote users to ADMIN
- USER role has no update privileges
- Each violation throws specific exception for precise error handling
🌍 Endpoint | Method | Description | Access |
---|---|---|---|
/register |
POST | Register new user | 🌎 Public |
/login |
POST | Authenticate and get JWT | 🌎 Public |
/users |
GET | Get all users | 👤 USER, 🛠 MODERATOR, 👑 ADMIN |
/users/{id} |
PUT | Update user | 🛠 MODERATOR, 👑 ADMIN |
/users/{id} |
DELETE | Delete user | 👑 ADMIN only |
git clone https://github.com/Trela-dev/SpringSecurityJwtCRUD.git
cd SpringSecurityJwtCRUD
Navigate to project folder(where the pom.xml file is) and run following commadns Run the following command in the project directory to start the database container:
docker-compose up -d
mvn clean install
java -jar target/SpringSecurityJwtCRUD-0.0.1-SNAPSHOT.jar
The application should now be running on http://localhost:8080.
Use Postman to test endpoints:
POST http://localhost:8080/register
{
"username": "your_username",
"password": "your_password"
}
POST http://localhost:8080/login
After logging in, you will receive a JWT token in the
Authorization
header of the response.
Copy the token and use it in theAuthorization
header for all endpoints other than/login
and/register
.Format:
Authorization: Bearer your_token_here
In Postman, go to the Authorization tab, choose Bearer Token, and paste the token into the Token field.
{
"username": "your_username",
"password": "your_password"
}
GET http://localhost:8080/users
DELETE http://localhost:8080/users/3
PUT http://localhost:8080/users/3
{
"username": "new_username",
"password": "new_password"
}
Role | Username | Password |
---|---|---|
👑 Admin | admin |
admin |
🛠 Moderator | moderator |
moderator |
👤 User | user1 |
user1 |
👤 User | user2 |
user2 |
👤 User | user3 |
user3 |
👤 User | user4 |
user4 |
👤 User | user5 |
user5 |
Newly registered users are assigned the 👤 USER role by default.
The project includes a comprehensive test suite written in JUnit 5, using:
- Spring's WebMvcTest – for controller-level integration tests
- MockMvc – to simulate HTTP requests and test response handling
- Mockito – to mock service and repository layers
- Custom Mock Repositories – in-memory implementations for
UserRepository
andRoleRepository
- ✅ Successful and failed login scenarios with JWT token verification
- ✅ Successful and failed user registration
- ✅ Protected endpoints access with valid/invalid tokens
- ✅ Role-based access control (e.g., only admins can update/delete other admins)
- ✅ Conflict scenarios like registering an already existing user
- ✅ Forbidden actions (e.g., moderators trying to assign admin roles)
Modify settings like JWT secret or database details in application.properties
.
- Add refresh tokens
- Implement password reset
- 🏗 Production-ready security
- 🏛 Clean architecture (Separation of concerns, proper layer isolation)
- 🔍 Follows RESTful best practices
- 🐳 Ready for Docker deployment