Pular para conteúdo

Camadas da Arquitetura - ecosif-auth

Visão Geral das Camadas

O projeto ecosif-auth segue a arquitetura em camadas do Spring Boot, com separação clara de responsabilidades.

Estrutura de Camadas

┌─────────────────────────────────────────────────────────────┐
│                    PRESENTATION LAYER                       │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Controllers                                           │  │
│  │ - AuthController                                      │  │
│  │ - DockerLogsController                                │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Filters                                               │  │
│  │ - TokenAuthenticationFilter                           │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                     BUSINESS LAYER                          │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Services                                              │  │
│  │ - UserService / UserServiceImpl                       │  │
│  │ - LocalUserDetailService                              │  │
│  │ - ExternalAuthenticationService                       │  │
│  │ - io.ecosif.security.jwt.TokenProvider (starter)      │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ DTOs                                                  │  │
│  │ - LoginRequest                                        │  │
│  │ - LoginRequestAzure                                   │  │
│  │ - JwtAuthenticationResponse                           │  │
│  │ - UserInfo                                            │  │
│  │ - UserCreateAzureDTO                                  │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                      DATA ACCESS LAYER                      │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Repositories                                          │  │
│  │ - UserRepository                                      │  │
│  │ - RoleRepository                                      │  │
│  │ - BusinessAccountRepository                           │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Entities                                              │  │
│  │ - User                                                │  │
│  │ - Role                                                │  │
│  │ - BusinessAccount                                     │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                    INFRASTRUCTURE LAYER                     │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Database (PostgreSQL)                                 │  │
│  │ - Schema: public                                      │  │
│  │ - Tables: gr_user, roles, businessaccount             │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ Configuration                                         │  │
│  │ - WebSecurityConfig                                   │  │
│  │ - PasswordEncoderConfig                               │  │
│  │ - OpenApiConfig                                       │  │
│  │ - AppProperties                                       │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

1. Presentation Layer (Camada de Apresentação)

Controllers

Responsáveis por receber requisições HTTP, validar entradas e retornar respostas.

AuthController

  • Responsabilidade: Gerenciar autenticação de usuários
  • Endpoints:
  • POST /api/auth/signin: Autenticação local
  • POST /api/auth/external-login: Login Microsoft/Google (id_token)
  • Validações: Validação de DTOs usando Bean Validation
  • Tratamento de Erros: Utiliza GlobalExceptionHandler

DockerLogsController

  • Responsabilidade: Endpoints administrativos para visualização de logs
  • Endpoints:
  • GET /api/admin/docker-logs: Obter logs de um container
  • GET /api/admin/docker-logs/services: Listar serviços disponíveis
  • Segurança: Requer autenticação JWT

Filters

TokenAuthenticationFilter

  • Responsabilidade: Interceptar requisições e validar tokens JWT
  • Fluxo:
  • Extrai token do header Authorization
  • Valida token usando TokenProvider
  • Carrega usuário do banco de dados
  • Define contexto de segurança do Spring

2. Business Layer (Camada de Negócio)

Services

Implementam a lógica de negócio do sistema.

UserService / UserServiceImpl

  • Responsabilidade: Gerenciar operações de usuários
  • Métodos principais:
  • findUserByUsername(String email): Buscar usuário por username
  • findUserById(Long id): Buscar usuário por ID
  • save(User user): Salvar ou atualizar usuário
  • Transações: Métodos marcados com @Transactional

LocalUserDetailService

  • Responsabilidade: Integração com Spring Security
  • Implementa: UserDetailsService
  • Método principal: loadUserByUsername(String username)
  • Retorna: LocalUser (implementação de UserDetails)

TokenProvider (starter)

  • Pacote: io.ecosif.security.jwt.TokenProvider (ecosif-spring-boot-starter-security)
  • createToken(LocalUser userPrincipal): Criar novo token JWT
  • validateToken(String authToken): Validar token JWT
  • getUserIdFromToken(String token): Extrair username do token
  • Algoritmo: HS256 (HMAC SHA-256)

DTOs (Data Transfer Objects)

Objetos para transferência de dados entre camadas.

LoginRequest

  • Uso: Requisição de autenticação local
  • Campos:
  • username (String, obrigatório)
  • password (String, obrigatório)
  • azure (Boolean) — legado; se true retorna 400

ExternalLoginRequest

  • Uso: POST /api/auth/external-login
  • Campos: provider, token, tokenType

LoginRequestAzure (removido)

  • username (String, obrigatório)
  • userCreate (UserCreateAzureDTO, opcional)

JwtAuthenticationResponse

  • Uso: Resposta de autenticação bem-sucedida
  • Campos:
  • accessToken (String): Token JWT
  • user (UserInfo): Informações do usuário
  • tenantName (String): Nome do tenant

UserInfo

  • Uso: Informações do usuário autenticado
  • Campos:
  • id (String): ID do usuário
  • displayName (String): Nome completo
  • email (String): Email
  • roles (List): Lista de roles/perfis
  • tenant (String): Tenant/empresa

3. Data Access Layer (Camada de Acesso a Dados)

Repositories

Interfaces Spring Data JPA para acesso a dados.

UserRepository

  • Estende: JpaRepository<User, Long>
  • Métodos customizados:
  • findByUsername(String username): Buscar por username
  • existsByUsername(String email): Verificar existência por username

RoleRepository

  • Estende: JpaRepository<Role, Long>
  • Uso: Gerenciamento de roles (atualmente não muito utilizado)

BusinessAccountRepository

  • Estende: JpaRepository<BusinessAccount, Long>
  • Uso: Gerenciamento de contas de negócio (tenants)

Entities

Entidades JPA que representam tabelas do banco de dados.

User

  • Tabela: gr_user
  • Campos principais:
  • id (Long): ID primário
  • name (String): Nome completo
  • username (String): Username/email (único)
  • password (String): Senha criptografada (BCrypt)
  • active (boolean): Status ativo/inativo
  • role (String): Role/perfil do usuário
  • tenant (String): Tenant/empresa
  • expiryDate (Date): Data de expiração

Role

  • Tabela: roles
  • Campos principais:
  • id (Long): ID primário
  • name (String): Nome da role

BusinessAccount

  • Tabela: businessaccount
  • Campos principais:
  • id (Long): ID primário
  • name (String): Nome da conta (único)

4. Infrastructure Layer (Camada de Infraestrutura)

Database

PostgreSQL

  • Versão: 13+ (recomendado 15)
  • Schema: public
  • Tabelas principais:
  • gr_user: Usuários do sistema
  • roles: Roles/perfis (não muito utilizado)
  • businessaccount: Contas de negócio (tenants)

Flyway

  • Responsabilidade: Gerenciamento de migrações de banco de dados
  • Localização: src/main/resources/db/migration/
  • Convenção de nomenclatura: V{version}__{description}.sql

Configuration

WebSecurityConfig

  • Responsabilidade: Configuração de segurança Spring Security
  • Recursos configurados:
  • CORS
  • CSRF (desabilitado para API REST)
  • Autenticação JWT
  • OAuth2 (opcional)
  • Autorização de endpoints

PasswordEncoderConfig

  • Responsabilidade: Configuração do encoder de senhas
  • Algoritmo: BCrypt
  • Bean: PasswordEncoder

OpenApiConfig

  • Responsabilidade: Configuração do Swagger/OpenAPI
  • Biblioteca: SpringDoc OpenAPI 3.0
  • Endpoints:
  • Swagger UI: /swagger-ui.html
  • OpenAPI JSON: /v3/api-docs

AppProperties

  • Responsabilidade: Propriedades customizadas da aplicação
  • Propriedades:
  • app.auth.tokenSecret: Chave secreta JWT
  • app.auth.tokenExpirationMsec: Tempo de expiração do token

Fluxo de Dados entre Camadas

Exemplo: Processo de Autenticação

1. Cliente → Controller
   POST /api/auth/signin
   { username, password }

2. Controller → Service
   userService.findUserByUsername(username)

3. Service → Repository
   userRepository.findByUsername(username)

4. Repository → Database
   SELECT * FROM gr_user WHERE username = ?

5. Database → Repository
   User entity

6. Repository → Service
   User entity

7. Service → Controller
   User entity

8. Controller → AuthenticationManager
   authenticate(username, password)

9. AuthenticationManager → LocalUserDetailService
   loadUserByUsername(username)

10. LocalUserDetailService → Repository → Database
    (busca usuário novamente)

11. AuthenticationManager → Controller
    Authentication (com LocalUser)

12. Controller → TokenProvider
    createToken(localUser)

13. TokenProvider → Controller
    JWT Token

14. Controller → Cliente
    200 OK + JWT Token + UserInfo

Princípios de Design

Separation of Concerns (Separação de Responsabilidades)

  • Cada camada tem responsabilidades claras e bem definidas
  • Controllers não contêm lógica de negócio
  • Services não conhecem detalhes de apresentação
  • Repositories são apenas interfaces de acesso a dados

Dependency Inversion (Inversão de Dependências)

  • Camadas superiores dependem de abstrações (interfaces)
  • Implementações estão nas camadas inferiores
  • Facilita testes e manutenção

Single Responsibility (Responsabilidade Única)

  • Cada classe tem uma única responsabilidade
  • Facilita compreensão e manutenção do código

Don't Repeat Yourself (DRY)

  • Lógica comum é extraída para serviços compartilhados
  • Validações reutilizáveis são definidas em DTOs

Testabilidade

A arquitetura em camadas facilita testes unitários e de integração:

  • Controllers: Testáveis com @WebMvcTest
  • Services: Testáveis com mocks de repositories
  • Repositories: Testáveis com @DataJpaTest e banco em memória
  • TokenProvider: Testável de forma isolada