Este é um projeto base completo de API REST desenvolvido em Spring Boot com Spring Security totalmente configurado e pronto para uso. O projeto implementa um sistema robusto de autenticação e autorização baseado em JWT (JSON Web Tokens), servindo como template inicial para outros projetos que necessitam de funcionalidades de segurança.
Fornecer uma base sólida e pronta para uso com:
- Autenticação JWT completa
- Gerenciamento de usuários e roles
- Tratamento de exceções global
- Validação de dados
- Testes unitários e de integração
- Logging estruturado
- Migrações de banco de dados com Flyway
- Java 21 - Linguagem de programação
- Spring Boot 4.0.2 - Framework principal
- Spring Security - Framework de segurança
- Spring Data JPA - Abstração de acesso a dados
- Hibernate - ORM (Object-Relational Mapping)
- PostgreSQL - Banco de dados relacional
- Flyway - Controle de versão de banco de dados
- JWT (JJWT 0.12.5) - Geração e validação de tokens
- Lombok - Redução de boilerplate
- Bean Validation - Validação de dados
// Spring Boot Starters
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-flyway'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.12.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.5'
// Database
implementation 'org.flywaydb:flyway-database-postgresql'
runtimeOnly 'org.postgresql:postgresql'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Development
developmentOnly 'org.springframework.boot:spring-boot-devtools'testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-test-autoconfigure'
testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa-test'
testImplementation 'org.springframework.boot:spring-boot-starter-flyway-test'
testImplementation 'org.springframework.boot:spring-boot-starter-security-test'
testImplementation 'org.junit.platform:junit-platform-suite-api'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'src/main/java/com/dvlprmatheus/security/
├── api/
│ ├── controller/ # Controllers REST
│ │ ├── AuthenticationController.java
│ │ └── UserController.java
│ ├── exception/ # Exceções customizadas e handler global
│ │ ├── AuthenticationFailedException.java
│ │ ├── EmailAlreadyExistsException.java
│ │ ├── GlobalExceptionHandler.java
│ │ ├── ResourceNotFoundException.java
│ │ └── UsernameAlreadyExistsException.java
│ ├── request/ # DTOs de requisição
│ │ ├── LoginRequest.java
│ │ └── RegisterRequest.java
│ └── response/ # DTOs de resposta
│ ├── AuthResponse.java
│ ├── ErrorResponse.java
│ └── TestResponse.java
├── config/
│ ├── jwt/ # Configurações JWT
│ │ └── JwtProperties.java
│ └── security/ # Configurações de segurança
│ ├── SecurityConfig.java
│ └── filter/
│ └── JwtAuthenticationFilter.java
├── entity/ # Entidades JPA
│ ├── AbstractEntity.java
│ ├── Role.java
│ └── User.java
├── repository/ # Repositórios Spring Data JPA
│ ├── RoleRepository.java
│ └── UserRepository.java
├── service/ # Camada de serviços
│ ├── AuthenticationService.java
│ └── UserService.java
└── utils/ # Utilitários
└── JwtUtil.java
- Geração de Tokens: Tokens JWT são gerados após login bem-sucedido
- Validação Automática: Filtro customizado valida tokens em cada requisição
- Expiração Configurável: Tokens com tempo de expiração configurável (padrão: 24 horas)
- Extração de Claims: Extração segura de informações do token
- Registro de Usuários: Endpoint para criação de novos usuários
- Login: Autenticação com username e senha
- Validação de Credenciais: Validação robusta de dados de entrada
- Prevenção de Duplicatas: Verificação de username e email únicos
- Sistema de Roles: Suporte a múltiplas roles por usuário
- Many-to-Many: Relacionamento flexível entre usuários e roles
- Autorities: Integração com Spring Security Authorities
O projeto utiliza application.yaml com as seguintes configurações principais:
spring:
datasource:
url: jdbc:postgresql://postgresdb:5432/${DB_NAME:postgres}
username: ${DB_USER:postgres}
password: ${DB_PASSWORD:postgres}
hikari:
maximum-pool-size: 10
jpa:
hibernate:
ddl-auto: none # Flyway gerencia o schema
show-sql: true
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
out-of-order: true
jwt:
expiration: 86400000 # 24 horas em milissegundos
secret: ${JWT_SECRET:...} # Configurar via variável de ambienteDB_NAME: Nome do banco de dados (padrão: postgres)DB_USER: Usuário do banco (padrão: postgres)DB_PASSWORD: Senha do banco (padrão: postgres)JWT_SECRET: Chave secreta para assinatura JWT (obrigatório em produção)
O projeto possui uma suíte completa de testes utilizando JUnit 5 e Mockito:
-
AuthenticationServiceTest: Testa a lógica de negócio de autenticação
- Registro de usuários
- Validação de duplicatas
- Login com credenciais válidas/inválidas
- Geração de tokens JWT
-
JwtUtilTest: Testa utilitários de JWT
- Geração de tokens
- Extração de claims
- Validação de tokens
- Verificação de expiração
-
AuthenticationControllerTest: Testa endpoints de autenticação
- POST
/auth/register- Registro de usuários - POST
/auth/login- Login de usuários - Validação de requisições
- Tratamento de erros
- POST
-
UserControllerTest: Testa endpoints protegidos
- GET
/v1/user/test- Verificação de autenticação - Comportamento com/sem autenticação
- GET
-
SecurityApplicationTests: Teste de contexto Spring
- Verificação de carregamento do contexto
# Executar todos os testes
./gradlew test
# Executar testes com relatório
./gradlew test --info
# Executar apenas testes unitários
./gradlew test --tests "*Test"
# Executar apenas testes de integração
./gradlew test --tests "*ControllerTest"Registra um novo usuário no sistema.
Request Body:
{
"username": "usuario123",
"email": "[email protected]",
"password": "senha123456"
}Response (201 Created):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"type": "Bearer",
"username": "usuario123"
}Autentica um usuário e retorna um token JWT.
Request Body:
{
"username": "usuario123",
"password": "senha123456"
}Response (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"type": "Bearer",
"username": "usuario123"
}Endpoint de teste para verificar autenticação.
Headers:
Authorization: Bearer <token>
Response (200 OK):
{
"message": "Authentication working correctly!",
"username": "usuario123"
}O projeto implementa um GlobalExceptionHandler que centraliza o tratamento de todas as exceções:
AuthenticationFailedException: Falha na autenticaçãoEmailAlreadyExistsException: Email já cadastradoUsernameAlreadyExistsException: Username já cadastradoResourceNotFoundException: Recurso não encontrado
Todas as exceções retornam um formato padronizado:
{
"timestamp": "2024-01-01T12:00:00",
"status": 400,
"error": "Bad Request",
"message": "Validation error in provided data",
"path": "/auth/register",
"fieldErrors": [
{
"field": "email",
"message": "Email must be valid",
"rejectedValue": "invalid-email"
}
]
}O projeto utiliza SLF4J com Lombok para logging estruturado:
- @Slf4j: Anotação do Lombok que gera automaticamente o logger
- Níveis de Log:
log.info(): Operações importantes (registro, login)log.debug(): Informações detalhadas para debuglog.warn(): Avisos (credenciais inválidas, tokens inválidos)log.error(): Erros inesperados
INFO - Attempting to register new user with username: usuario123
DEBUG - User created successfully with ID: 1
INFO - User registered successfully: usuario123
WARN - Login failed: invalid credentials for user: usuario123
O projeto utiliza Flyway para versionamento do banco de dados:
V1__create_roles_table.sql: Criação da tabela de rolesV2__create_users_table.sql: Criação da tabela de usuáriosV3__create_user_roles_table.sql: Tabela de relacionamento usuário-role
-
User: Entidade principal de usuário
- Campos: id, username, email, password, createdAt, updatedAt
- Relacionamento Many-to-Many com Role
-
Role: Entidade de permissões
- Campos: id, name, createdAt, updatedAt
- Relacionamento Many-to-Many com User
- JWT Authentication Filter: Filtro customizado para validação de tokens
- Password Encoding: Uso de BCrypt para hash de senhas
- CORS: Configuração de Cross-Origin Resource Sharing
- CSRF: Proteção CSRF configurada
- Session Management: Gerenciamento de sessão stateless
- Bean Validation: Validação de dados de entrada
- Custom Validators: Validações específicas de negócio
- Constraint Violations: Tratamento de violações de constraints
git clone <repository-url>
cd spring-security-apiCrie um arquivo .env ou configure as variáveis:
export DB_NAME=seu_banco
export DB_USER=seu_usuario
export DB_PASSWORD=sua_senha
export JWT_SECRET=sua_chave_secreta_aleatoriaAs migrações Flyway são executadas automaticamente na inicialização.
./gradlew bootRun# Registrar usuário
curl -X POST http://localhost:8080/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"teste","email":"[email protected]","password":"senha123"}'
# Login
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"teste","password":"senha123"}'
# Endpoint protegido
curl -X GET http://localhost:8080/v1/user/test \
-H "Authorization: Bearer <token>"Este projeto base pode ser facilmente estendido com:
- Novos Endpoints: Adicionar controllers na pasta
api/controller - Novas Entidades: Criar entidades em
entitye repositórios emrepository - Novos Serviços: Implementar serviços em
service - Novas Roles: Adicionar roles no banco e configurar autorização
- Novas Validações: Criar validators customizados
- Novos Filtros: Adicionar filtros de segurança
Este projeto está sob licença. Consulte o arquivo LICENSE para mais detalhes.
Este é um projeto base destinado a ser usado como template. Sinta-se livre para:
- Fazer fork do projeto
- Criar uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abrir um Pull Request
- Spring Security Documentation
- JWT.io - Documentação sobre JWT
- Spring Boot Documentation
- Flyway Documentation