A production-ready REST API built with Spring Boot 3 featuring JWT authentication, role-based access control, and full security hardening.
| Layer | Technology |
|---|---|
| Language | Java 21 |
| Framework | Spring Boot 3.3 |
| Security | Spring Security + JWT (jjwt 0.12) |
| Database | PostgreSQL (prod) / H2 (dev) |
| Build Tool | Maven |
| Containerization | Docker |
- ✅ JWT Authentication (login → token → access)
- ✅ Role-based access control (
ROLE_ADMIN,ROLE_USER) - ✅ Global exception handling with consistent error responses
- ✅ Input validation on all request bodies
- ✅ Structured logging (JSON in prod, readable in dev)
- ✅ Dev / Prod profile separation
- ✅ Health check endpoint via Spring Actuator
- ✅ Dockerized for easy deployment
src/
├── main/java/com/example/
│ ├── auth/ # Login endpoint
│ ├── exception/ # Global error handler
│ ├── security/ # JWT filter, service, config
│ └── user/ # User entity, repository, service
├── main/resources/
│ ├── application-dev.properties
│ └── application-prod.properties
└── test/
├── auth/ # Integration tests
└── security/ # JWT unit tests
- Java 21+
- Maven 3.8+
- PostgreSQL (for prod) or just run dev profile with H2
git clone https://github.com/YOUR_USERNAME/product-service.git
cd product-service./mvnw spring-boot:run -Dspring-boot.run.profiles=devApp starts at: http://localhost:8080
POST /auth/login → returns JWT token
GET /products → requires Bearer token
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiJ9...",
"tokenType": "Bearer"
}curl http://localhost:8080/products \
-H "Authorization: Bearer YOUR_TOKEN_HERE"| Username | Password | Role |
|---|---|---|
| admin | admin123 | ADMIN + USER |
| user | user123 | USER |
⚠️ These are seeded automatically in dev profile only. Never use in production.
| Method | Endpoint | Access | Description |
|---|---|---|---|
| POST | /auth/login |
Public | Get JWT token |
| GET | /products |
USER, ADMIN | List all products |
| POST | /products |
ADMIN only | Create product |
| PUT | /products/{id} |
ADMIN only | Update product |
| DELETE | /products/{id} |
ADMIN only | Delete product |
| GET | /actuator/health |
Public | Health check |
# Build image
docker build -t product-service .
# Run with environment variables
docker run -p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_DATASOURCE_URL=jdbc:postgresql://host:5432/mydb \
-e SPRING_DATASOURCE_USERNAME=postgres \
-e SPRING_DATASOURCE_PASSWORD=yourpassword \
-e JWT_SECRET=your_base64_secret \
product-service| Variable | Description |
|---|---|
SPRING_DATASOURCE_URL |
PostgreSQL connection URL |
SPRING_DATASOURCE_USERNAME |
DB username |
SPRING_DATASOURCE_PASSWORD |
DB password |
JWT_SECRET |
Base64-encoded secret (min 64 bytes) |
Generate a secure JWT secret:
openssl rand -base64 64./mvnw testMIT License — free to use and modify.