Um projeto Backend em Java com Spring Boot desenvolvido como parte do módulo "Simplificando a Segurança em APIs REST com Spring Security" do Bootcamp "NTT Data: Backend Java com Spring AI", parceria entre a DIO e a NTT Data. Este projeto foca em demonstrar a implementação de Spring Security com autenticação baseada em JSON, controle de acesso por roles (RBAC) e uma arquitetura clean com separação de responsabilidades.
-
ConfiguraÇão de Segurança (
SecurityConfig)- Uso de
@Configuratione@EnableWebSecuritypara inicializar a configuração de segurança - Habilitação de
@EnableMethodSecuritypara controle de acesso em nível de método - Configuração de
SecurityFilterChaincomo ponto de entrada de autenticação - Desabilitação de CSRF para facilitar testes em APIs REST
- Definição de regras de autorização com
authorizeHttpRequests()
- Uso de
-
Filtros de Autenticação Customizados`
- Extensão de
UsernamePasswordAuthenticationFilterpara processar JSON em vez de form-data - Implementação de autenticação REST via
/api/auth/logincomObjectMapper(Jackson) - Gerenciamento de
AuthenticationManageratravés deAuthenticationConfiguration - Customização de handler de sucesso para retornar status HTTP 200 ao invés de redirecionar
- Extensão de
-
Carregamento de Usuários
- Implementação de
UserDetailsServicecomJpaUserDetailsServices - Integração com repositório JPA para buscar usuários do banco de dados
- Lançamento de
UsernameNotFoundExceptionpara usuários não encontrados
- Implementação de
-
Encoding de Senhas
- Uso de
BCryptPasswordEncoderpara hashing seguro de senhas - Inicialização em memória de usuários de teste com senhas criptografadas
- Uso de
-
Autorização Baseada em Roles (RBAC)
- Uso de
@PreAuthorizecomhasRole()para controle granular de acesso - Suporte a múltiplos roles (INFLUENCER, BRAND)
@AuthenticationPrincipalpara injetar usuário autenticado nos controllers
- Uso de
-
Arquitetura Limpa (Clean Architecture)
- Separação clara entre domain, application e infrastructure
- Inversão de dependências para facilitar testes
- Use Cases como orquestração de lógica de negócio
-
Dependency Injection
- Uso de construtores para injeção de dependências (melhor prática)
@Servicee@Componentpara registro de beans- Ciclo de vida gerenciado pelo Spring
-
Padrões de Design
- Value Objects:
ProposalId,OwnerIdpara encapsular tipos simples - DTOs (Data Transfer Objects): Input e Output para separar dados trafegados da lógica interna
- Use Case Pattern: Classes como
CreateProposalUseCaseseguindo princípio de Single Responsibility
- Value Objects:
-
Framework Integrations
- Spring Data JPA para persistência
- Spring Web para endpoints REST
- Lombok para redução de boilerplate
- Spring Boot Docker Compose para infraestrutura local
src/main/java/marcio/proposalmanagement/
│
├── ProposalManagementApplication.java # Classe principal da aplicação (@SpringBootApplication)
│
├── auth/ # Módulo de Autenticação e Segurança
│ ├── application/ # Camada de aplicação (casos de uso)
│ │
│ ├── domain/ # Camada de domínio
│ │ └── UserRole.java # Enum com roles disponíveis (INFLUENCER, BRAND)
│ │
│ └── infrastructure/ # Camada de infraestrutura
│ ├── http/
│ │ └── Controller.java # Endpoints REST de teste com @PreAuthorize
│ │
│ ├── persistence/
│ │ ├── entity/ # Entidades JPA mapeadas para BD
│ │ └── repository/ # Interfaces repository para operações BD
│ │
│ └── security/
│ ├── SecurityConfig.java # Configuração centralizada de segurança
│ ├── JpaUserDetailsServices.java # Serviço de carregamento de usuários
│ └── RestUsernamePasswordAuthenticationFilter.java # Filtro customizado para autenticação JSON
│
└── proposal/ # Módulo de Propostas
├── application/ # Camada de aplicação
│ ├── CreateProposalUseCase.java # Case de uso para criação de propostas
│ ├── ListProposalUseCase.java # Case de uso para listagem de propostas
│ ├── input/ # DTOs de entrada
│ ├── list/ # Estruturas para listagem
│ └── output/ # DTOs de saída
│
├── domain/ # Camada de domínio (lógica de negócio)
│ ├── Proposal.java # Entidade de domínio Proposal
│ ├── ProposalId.java # Value Object para ID de proposta
│ ├── Owner.java # Entidade de domínio Owner
│ ├── OwnerId.java # Value Object para ID de owner
│ └── ProposalRepository.java # Interface de persistência (inversão de dependência)
│
└── infrastructure/ # Camada de infraestrutura
├── http/
│ └── ProposalController.java # Endpoints REST para propostas
│
└── persistence/
├── entity/ # Entidades JPA
└── repository/ # Implementações de repository com Spring Data JPA
Responsabilidade: Gerenciar autenticação, autorização e segurança da aplicação.
domain/: Define conceitos de segurança como roles de usuáriosinfrastructure/security/: Implementa mecanismos de segurança (filtros, providers, configurações)infrastructure/persistence/: Persiste dados de usuários no banco de dadosinfrastructure/http/: Expõe endpoints para validar acesso com base em roles
Responsabilidade: Gerenciar propostas de projetos (criação, listagem, etc).
domain/: Lógica pura de negócio e estrutura de dados de propostaapplication/: Casos de uso (orquestra domínio + repositórios)infrastructure/: Detalhes técnicos (controllers REST, persistência JPA)
| Tecnologia | Versão | Propósito |
|---|---|---|
| Java | 25 | Linguagem principal |
| Spring Boot | 4.0.6 | Framework principal |
| Spring Security | Latest | Autenticação e autorização |
| Spring Data JPA | Latest | Persistência de dados |
| Spring Web | Latest | Endpoints REST |
| MySQL | Latest | Banco de dados |
| Lombok | 9.2.0 | Redução de boilerplate |
| Jackson | Latest | Serialização JSON |
| BCrypt | Latest | Hashing de senhas |
1. Cliente envia POST /api/auth/login com JSON { "username": "...", "password": "..." }
↓
2. RestUsernamePasswordAuthenticationFilter intercepta a requisição
↓
3. ObjectMapper converte JSON para LoginRequest
↓
4. UsernamePasswordAuthenticationToken é criado
↓
5. AuthenticationManager valida credenciais via JAUnautenticatedTokenPAUserDetailsService
↓
6. JpaUserDetailsServices carrega User do banco de dados
↓
7. BCryptPasswordEncoder valida a senha
↓
8. Se válido: SecurityContext armazena autenticação (sessão)
Se inválido: AuthenticationException é lançada
↓
9. Requisições subsequentes carregam contexto de segurança automaticamente
@GetMapping("/influencer")
@PreAuthorize("hasRole('INFLUENCER')") // Apenas usuários com ROLE_INFLUENCER
public String influenceEndpoint() {
return "Hello World Influence";
}
@AuthenticationPrincipal User user // Injeta usuário autenticado
public String hello(@AuthenticationPrincipal User user) {
return "Hello World " + user.getId();
}- SOLID Principles: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
- DDD (Domain-Driven Design): Separação clara entre domínio e infraestrutura
- Clean Architecture: Camadas independentes com responsabilidades bem definidas
- Constructor Injection: Todas as dependências injetadas via construtor (melhor testabilidade)
- Value Objects:
ProposalId,OwnerIdpara type-safety
- ✅ Spring Security não é "apenas" autenticação - é um framework completo de segurança
- ✅ Filtros interceptam requisições no nível mais baixo - antes dos controllers
- ✅
@PreAuthorizepermite controle fino de acesso em métodos específicos - ✅
AuthenticationManageré a entidade central que valida credenciais - ✅ Uma boa arquitetura facilita múltiplos mecanismos de autenticação (form, JSON, OAuth, etc)
- ✅ Value Objects aumentam type-safety comparado a strings/longs simples
- Implementar JWT (JSON Web Token) para autenticação stateless
- Adicionar OAuth2 com Spring Security
- Implementar testes unitários e de integração
- Adicionar validação com Bean Validation
- Implementar rate limiting
- Adicionar logging e auditoria de segurança
- Documentação com Swagger/OpenAPI
Simplificando a Segurança em APIs REST com Spring Securit" 🎓