Aplicación de autenticación y autorización construida con Spring Boot 3.3.0 y Spring Security 6, siguiendo Arquitectura Hexagonal y Domain-Driven Design (DDD).
El proyecto está estructurado siguiendo los principios de Arquitectura Hexagonal:
src/main/java/com/bkseducate/securityapp/
├── domain/ # Capa de dominio (sin dependencias externas)
│ ├── model/ # Entidades de dominio (User, Role, RefreshToken)
│ ├── ports/ # Interfaces (puertos) del dominio
│ └── exceptions/ # Excepciones de dominio
├── application/ # Capa de aplicación
│ ├── usecase/ # Casos de uso
│ ├── dto/ # Data Transfer Objects
│ └── mapper/ # Mappers MapStruct
├── infrastructure/ # Capa de infraestructura
│ ├── security/ # JWT, Password, SecurityConfig
│ ├── persistence/ # Entidades JPA, Repositorios
│ └── exception/ # Manejo global de excepciones
└── adapters/ # Adaptadores
├── in/ # Controladores REST (adaptadores de entrada)
└── out/ # Adaptadores de persistencia (adaptadores de salida)
- ✅ Autenticación con JWT (Access Token + Refresh Token)
- ✅ Registro de usuarios con asignación automática de ROL_USER
- ✅ Refresh Token persistido en base de datos
- ✅ Cambio de contraseña
- ✅ Asignación de roles (requiere ADMIN)
- ✅ Logout con invalidación de refresh token
- ✅ Manejo global de excepciones
- ✅ Validación de entrada con Jakarta Validation
- ✅ MapStruct para mapeos DTO ↔ Dominio
- ✅ Arquitectura Hexagonal pura (dominio sin dependencias de Spring)
- ✅ Documentación API con Swagger/OpenAPI (SpringDoc)
- Java 17+
- Maven 3.6+
- MySQL 8.0+ (o superior)
El proyecto usa perfiles de Spring Boot para diferentes entornos:
- dev (por defecto): Desarrollo con MySQL local
- prod: Producción con MySQL configurado
export SPRING_PROFILES_ACTIVE=dev
export DB_URL=jdbc:mysql://localhost:3306/security_app_dev?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC
export DB_USERNAME=root
export DB_PASSWORD=tu_password
export JWT_SECRET=tu-secreto-super-seguro-aquiexport SPRING_PROFILES_ACTIVE=prod
export DB_URL=jdbc:mysql://tu-servidor:3306/security_app_prod?useSSL=true&requireSSL=true&serverTimezone=UTC
export DB_USERNAME=usuario_prod
export DB_PASSWORD=password_seguro_prod
export JWT_SECRET=tu-secreto-super-seguro-aqui # OBLIGATORIO en producción
export SERVER_PORT=8080application.yml: Configuración base comúnapplication-dev.yml: Configuración para desarrolloapplication-prod.yml: Configuración para producciónapplication-local.yml.example: Plantilla para configuración local (copia y renombra)
jwt.secret: Secreto para firmar tokens JWT (obligatorio en producción)jwt.access-token-expiration: Expiración del access token (900000ms = 15 min)jwt.refresh-token-expiration: Expiración del refresh token (604800000ms = 7 días)spring.datasource.*: Configuración de conexión a MySQL
Ver docs/DATABASE_SETUP.md para más detalles sobre la configuración de la base de datos.
# Compilar
mvn clean install
# Ejecutar
mvn spring-boot:runLa aplicación estará disponible en http://localhost:8080
Una vez que la aplicación esté ejecutándose, accede a la documentación interactiva:
http://localhost:8080/swagger-ui.html
Desde Swagger UI puedes:
- Ver todos los endpoints disponibles
- Probar los endpoints directamente desde el navegador
- Ver los modelos de datos (DTOs)
- Autenticarte con JWT para probar endpoints protegidos
La especificación OpenAPI está disponible en:
- JSON:
http://localhost:8080/v3/api-docs - YAML:
http://localhost:8080/v3/api-docs.yaml
Para más detalles sobre la configuración y uso de Swagger, consulta docs/SWAGGER_OPENAPI_SETUP.md.
POST /auth/register- Registro de usuarioPOST /auth/login- Login (retorna access token y refresh token)POST /auth/refresh- Refrescar access token
GET /auth/me- Obtener usuario autenticadoPUT /auth/change-password- Cambiar contraseñaPOST /auth/logout- Cerrar sesiónPUT /users/{userId}/roles- Asignar rol (requiere ADMIN)
Incluir el token en el header:
Authorization: Bearer <access_token>
curl -X POST http://localhost:8080/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'Respuesta:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "550e8400-e29b-41d4-a716-446655440000",
"tokenType": "Bearer",
"expiresIn": 900
}curl -X GET http://localhost:8080/auth/me \
-H "Authorization: Bearer <access_token>"curl -X POST http://localhost:8080/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "550e8400-e29b-41d4-a716-446655440000"
}'curl -X PUT http://localhost:8080/auth/change-password \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "password123",
"newPassword": "newpassword456"
}'curl -X PUT http://localhost:8080/users/{userId}/roles \
-H "Authorization: Bearer <admin_access_token>" \
-H "Content-Type: application/json" \
-d '{
"role": "ADMIN"
}'ROLE_USER- Asignado por defecto al crear usuarioROLE_ADMIN- Requerido para asignar rolesROLE_MODERATOR- Rol adicional disponible
mvn testmvn clean packageEl JAR ejecutable se generará en target/security-app-1.0.0-SNAPSHOT.jar
Ejecutar JAR:
java -jar target/security-app-1.0.0-SNAPSHOT.jarEl proyecto usa MySQL como base de datos principal.
- Asegúrate de tener MySQL ejecutándose
- Configura las variables de entorno (ver sección Configuración)
- La aplicación creará automáticamente la base de datos si no existe (en desarrollo)
CREATE DATABASE security_app_dev CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE security_app_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;Para más detalles, consulta docs/DATABASE_SETUP.md.
El proyecto está diseñado para ser fácilmente extensible:
- OAuth2/Keycloak: Implementar nuevos adaptadores en
infrastructure/security - Otras bases de datos: Cambiar solo los adaptadores en
adapters/out/persistence - Nuevos casos de uso: Agregar en
application/usecasesin modificar el dominio - Nuevos endpoints: Agregar controladores en
adapters/in/rest
- Arquitectura Hexagonal: Separación clara entre dominio, aplicación e infraestructura
- DDD: Modelo de dominio rico con entidades, value objects y excepciones
- SOLID: Principios aplicados en toda la arquitectura
- Clean Code: Código limpio, documentado y mantenible
- Security Best Practices: JWT seguro, contraseñas hasheadas, tokens revocables
Desarrollado siguiendo las mejores prácticas de Spring Boot y arquitectura de software.
Este proyecto es de uso educativo y demostrativo.