From 7544013e0b0c50c096ffc7e61651d3fa5ee432f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:38:05 +0000 Subject: [PATCH 1/3] Initial plan From d0cc1de28b6522e988c8d89ba844961bf2d655ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:41:54 +0000 Subject: [PATCH 2/3] Add comprehensive authentication documentation Co-authored-by: jvras58 <48683351+jvras58@users.noreply.github.com> --- DOCS/AUTHENTICATION.MD | 541 +++++++++++++++++++++++++++++++++++++++++ README.MD | 9 + 2 files changed, 550 insertions(+) create mode 100644 DOCS/AUTHENTICATION.MD diff --git a/DOCS/AUTHENTICATION.MD b/DOCS/AUTHENTICATION.MD new file mode 100644 index 0000000..c79070a --- /dev/null +++ b/DOCS/AUTHENTICATION.MD @@ -0,0 +1,541 @@ +# šŸ” **SISTEMA DE AUTENTICAƇƃO - GUIA COMPLETO** + +## šŸ“‹ **VISƃO GERAL** + +Este projeto utiliza um sistema de autenticação robusto baseado em **JWT (JSON Web Tokens)** para garantir a seguranƧa das operaƧƵes da API. O sistema trabalha em conjunto com o modelo **RBAC (Role-Based Access Control)** para fornecer controle granular de acesso. + +### **Componentes Principais** +- **JWT Tokens**: Tokens de acesso para autenticação de usuĆ”rios +- **BCrypt**: Hash seguro de senhas +- **OAuth2**: PadrĆ£o de autenticação com senha +- **python-jose**: Biblioteca para geração e validação de tokens JWT + +--- + +## šŸ”„ **FLUXO DE AUTENTICAƇƃO** + +```mermaid +sequenceDiagram + participant Cliente + participant API + participant DB + participant JWT + + Cliente->>API: POST /auth/token (username, password) + API->>DB: Buscar usuĆ”rio por username + DB-->>API: Retorna dados do usuĆ”rio + API->>API: Verificar senha (bcrypt) + API->>JWT: Gerar token JWT + JWT-->>API: Token gerado + API-->>Cliente: {access_token, token_type} + + Cliente->>API: GET /users/me (Authorization: Bearer token) + API->>JWT: Validar e decodificar token + JWT-->>API: Dados do usuĆ”rio extraĆ­dos + API->>DB: Buscar usuĆ”rio completo + DB-->>API: Dados do usuĆ”rio + API-->>Cliente: InformaƧƵes do usuĆ”rio +``` + +--- + +## šŸš€ **OBTENDO UM TOKEN DE ACESSO** + +### **1. Endpoint de Login** + +```http +POST /auth/token +Content-Type: application/x-www-form-urlencoded + +username=seu_usuario&password=sua_senha +``` + +### **2. Usando cURL** + +```bash +curl -X POST "http://localhost:8000/auth/token" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "username=admin&password=senha123" +``` + +### **3. Resposta Bem-Sucedida** + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "token_type": "bearer" +} +``` + +### **4. PossĆ­veis Erros** + +| Código | Descrição | Motivo | +|--------|-----------|--------| +| 400 | Bad Request | Credenciais incorretas (usuĆ”rio ou senha invĆ”lidos) | +| 422 | Unprocessable Entity | Formato de requisição invĆ”lido | + +--- + +## šŸ”‘ **ESTRUTURA DO TOKEN JWT** + +### **CabeƧalho (Header)** +```json +{ + "alg": "HS256", + "typ": "JWT" +} +``` + +### **Payload (Dados)** +```json +{ + "sub": "nome_usuario", + "exp": 1234567890, + "nbf": 1234567890, + "iat": 1234567890, + "iss": "FA-Backend" +} +``` + +### **Campos do Payload** +| Campo | Descrição | +|-------|-----------| +| `sub` | Subject - Nome de usuĆ”rio (username) | +| `exp` | Expiration Time - Data/hora de expiração do token | +| `nbf` | Not Before - Data/hora antes da qual o token nĆ£o Ć© vĆ”lido | +| `iat` | Issued At - Data/hora em que o token foi emitido | +| `iss` | Issuer - Emissor do token (FA-Backend) | + +### **ConfiguraƧƵes de Tempo** +- **Validade do Token**: ConfigurĆ”vel via `SECURITY_ACCESS_TOKEN_EXPIRE_MINUTES` (padrĆ£o: 30 minutos) +- **Algoritmo**: HS256 (configurĆ”vel via `SECURITY_ALGORITHM`) +- **Chave Secreta**: Armazenada em `.secrets/SECURITY_API_SECRET_KEY` + +--- + +## šŸ”’ **USANDO TOKENS NAS REQUISIƇƕES** + +### **1. Incluir Token no CabeƧalho** + +```http +GET /users/me +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... +``` + +### **2. Exemplo com cURL** + +```bash +curl -X GET "http://localhost:8000/users/me" \ + -H "Authorization: Bearer SEU_TOKEN_AQUI" +``` + +### **3. Exemplo com Python (requests)** + +```python +import requests + +token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +headers = {"Authorization": f"Bearer {token}"} + +response = requests.get( + "http://localhost:8000/users/me", + headers=headers +) +``` + +### **4. Exemplo com JavaScript (fetch)** + +```javascript +const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."; + +fetch("http://localhost:8000/users/me", { + headers: { + "Authorization": `Bearer ${token}` + } +}) +.then(response => response.json()) +.then(data => console.log(data)); +``` + +--- + +## šŸ›”ļø **SEGURANƇA DE SENHAS** + +### **Hash de Senhas com BCrypt** + +O sistema utiliza **BCrypt** para armazenar senhas de forma segura: + +1. **Criação de Senha**: + - Senha em texto plano Ć© recebida + - Salt aleatório Ć© gerado + - Senha Ć© hasheada com o salt + - Hash Ć© armazenado no banco de dados + +2. **Verificação de Senha**: + - UsuĆ”rio envia senha em texto plano + - Sistema busca hash armazenado + - BCrypt compara senha com hash + - Retorna verdadeiro ou falso + +### **FunƧƵes de SeguranƧa** + +#### `get_password_hash(password: str) -> str` +```python +# Uso: Ao criar ou atualizar senha de usuĆ”rio +hashed = get_password_hash("senha_do_usuario") +# Retorna: "$2b$12$KIXxH9e7..." +``` + +#### `verify_password(plain_password: str, hashed_password: str) -> bool` +```python +# Uso: Ao validar login +is_valid = verify_password("senha_do_usuario", hashed_from_db) +# Retorna: True ou False +``` + +#### `create_access_token(data: dict) -> str` +```python +# Uso: Ao gerar token após login bem-sucedido +token = create_access_token({"sub": "nome_usuario"}) +# Retorna: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +``` + +#### `extract_username(jwt_token: str) -> str` +```python +# Uso: Ao validar token e extrair usuĆ”rio +username = extract_username(token) +# Retorna: "nome_usuario" +``` + +--- + +## šŸ‘¤ **OBTENDO O USUƁRIO ATUAL** + +### **DependĆŖncia FastAPI** + +O sistema fornece uma dependĆŖncia `get_current_user` para obter o usuĆ”rio autenticado: + +```python +from app.api.authentication.controller import get_current_user +from app.models.user import User +from fastapi import Depends + +@router.get("/protected-route") +async def protected_route( + current_user: User = Depends(get_current_user) +): + return {"username": current_user.username} +``` + +### **Processo de Validação** + +1. **Extração do Token**: Token Ć© extraĆ­do do cabeƧalho `Authorization` +2. **Decodificação JWT**: Token Ć© decodificado e validado +3. **Extração do Username**: Campo `sub` do payload Ć© extraĆ­do +4. **Busca no Banco**: UsuĆ”rio Ć© buscado no banco de dados +5. **Retorno**: Objeto `User` completo Ć© retornado + +### **ExceƧƵes PossĆ­veis** + +| Exceção | Código HTTP | Quando Ocorre | +|---------|-------------|---------------| +| `CredentialsValidationException` | 401 | Token invĆ”lido, expirado ou usuĆ”rio nĆ£o encontrado | +| `IncorrectCredentialException` | 400 | Username ou senha incorretos no login | + +--- + +## šŸ”— **INTEGRAƇƃO COM RBAC** + +### **Fluxo Completo: Autenticação + Autorização** + +``` +1. Login (Autenticação) + ↓ +2. Token JWT Gerado + ↓ +3. Token em Requisição Protegida + ↓ +4. Validar Token → Obter UsuĆ”rio + ↓ +5. Validar PermissĆ£o (RBAC) + ↓ +6. Executar Operação ou Negar Acesso +``` + +### **Validação de PermissƵes** + +```python +from app.api.authorization.controller import validate_transaction_access +from app.api.authentication.controller import get_current_user + +@router.post("/users/create") +async def create_user( + db_session: Session, + current_user: User = Depends(get_current_user) +): + # Valida se usuĆ”rio tem permissĆ£o para criar usuĆ”rios + validate_transaction_access( + db_session, + current_user, + 'OP_1040001' # Código da operação "User - Create" + ) + + # UsuĆ”rio tem permissĆ£o, executar operação... +``` + +### **Cadeia de Validação RBAC** + +``` +Token JWT → User → Assignment → Role → Authorization → Transaction +``` + +Para mais detalhes sobre o sistema RBAC, consulte [PERMISSIONS.MD](PERMISSIONS.MD). + +--- + +## šŸ“ **CENƁRIOS PRƁTICOS** + +### **CenĆ”rio 1: Login e Acesso a Recurso Protegido** + +```bash +# 1. Fazer login e obter token +TOKEN=$(curl -s -X POST "http://localhost:8000/auth/token" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "username=admin&password=senha123" \ + | jq -r '.access_token') + +# 2. Usar token para acessar recurso protegido +curl -X GET "http://localhost:8000/users/me" \ + -H "Authorization: Bearer $TOKEN" +``` + +### **CenĆ”rio 2: Token Expirado** + +```bash +# Após 30 minutos (ou tempo configurado), o token expira +curl -X GET "http://localhost:8000/users/me" \ + -H "Authorization: Bearer TOKEN_EXPIRADO" + +# Resposta: +# HTTP 401 Unauthorized +# {"detail": "Could not validate credentials"} + +# Solução: Fazer novo login e obter novo token +``` + +### **CenĆ”rio 3: Criação de UsuĆ”rio Sem Autenticação** + +```bash +# Este Ć© o ÚNICO endpoint que nĆ£o requer autenticação +curl -X POST "http://localhost:8000/users/" \ + -H "Content-Type: application/json" \ + -d '{ + "username": "novo_usuario", + "display_name": "Novo UsuĆ”rio", + "email": "novo@email.com", + "password": "senha123" + }' + +# āš ļø IMPORTANTE: UsuĆ”rio criado nĆ£o tem NENHUMA permissĆ£o +# Um admin precisa atribuir um Role via Assignment +``` + +### **CenĆ”rio 4: Tentativa de Acesso Sem Token** + +```bash +curl -X GET "http://localhost:8000/users/" + +# Resposta: +# HTTP 401 Unauthorized +# {"detail": "Not authenticated"} +``` + +--- + +## āš™ļø **CONFIGURAƇƃO DO SISTEMA** + +### **VariĆ”veis de Ambiente (.env)** + +```plaintext +# Algoritmo de criptografia JWT +SECURITY_ALGORITHM=HS256 + +# Tempo de expiração do token em minutos +SECURITY_ACCESS_TOKEN_EXPIRE_MINUTES=30 + +# URL do banco de dados +DB_URL=sqlite:///database.db +``` + +### **Chave Secreta (.secrets/SECURITY_API_SECRET_KEY)** + +```bash +# Gerar chave secreta forte +openssl rand -hex 32 > .secrets/SECURITY_API_SECRET_KEY + +# Ou usar Python +python -c "import secrets; print(secrets.token_hex(32))" > .secrets/SECURITY_API_SECRET_KEY +``` + +āš ļø **IMPORTANTE**: +- NUNCA commite a chave secreta no repositório +- Use uma chave diferente para produção +- Mantenha a chave em local seguro + +--- + +## šŸ” **ARQUITETURA DO CƓDIGO** + +### **Estrutura de Arquivos** + +``` +app/api/authentication/ +ā”œā”€ā”€ router.py # Endpoint de login (/auth/token) +ā”œā”€ā”€ controller.py # Lógica de autenticação (login, validação) +└── schemas.py # Modelos Pydantic (AccessToken, TokenData) + +app/utils/ +ā”œā”€ā”€ security.py # FunƧƵes de seguranƧa (JWT, hash) +└── settings.py # ConfiguraƧƵes da aplicação +``` + +### **Fluxo de Código** + +1. **Router** (`router.py`): + - Define endpoint `/auth/token` + - Recebe credenciais via `OAuth2PasswordRequestForm` + - Chama controller para processar login + +2. **Controller** (`controller.py`): + - `execute_user_login()`: Valida credenciais e gera token + - `get_current_user()`: Extrai e valida usuĆ”rio do token + - Usa funƧƵes de `security.py` para operaƧƵes criptogrĆ”ficas + +3. **Security** (`security.py`): + - `create_access_token()`: Gera token JWT + - `verify_password()`: Valida senha com bcrypt + - `get_password_hash()`: Hash de senha para armazenamento + - `extract_username()`: Extrai username do token + +--- + +## 🧪 **TESTANDO O SISTEMA** + +### **Teste Manual via Swagger UI** + +1. Acesse: http://localhost:8000/api/v1/docs +2. VĆ” atĆ© o endpoint `/auth/token` +3. Clique em "Try it out" +4. Preencha username e password +5. Clique em "Execute" +6. Copie o `access_token` retornado +7. Clique no botĆ£o "Authorize" (cadeado) no topo da pĆ”gina +8. Cole o token no campo "Value" +9. Clique em "Authorize" +10. Agora vocĆŖ pode testar endpoints protegidos + +### **Teste com pytest** + +```bash +# Executar todos os testes +pytest tests/ + +# Executar testes de autenticação especĆ­ficos +pytest tests/ -k "auth" + +# Com cobertura +pytest --cov=app tests/ +``` + +--- + +## 🚨 **SEGURANƇA E BOAS PRƁTICAS** + +### āœ… **O Sistema Implementa** +- Hash seguro de senhas com BCrypt e salt aleatório +- Tokens JWT com expiração configurĆ”vel +- Validação de token em toda requisição protegida +- Chave secreta armazenada fora do código +- OAuth2 password flow padrĆ£o +- Timestamps completos em tokens (iat, nbf, exp) + +### āš ļø **RecomendaƧƵes** +- Use HTTPS em produção (nunca HTTP) +- Rotacione a chave secreta periodicamente +- Configure tempo de expiração adequado (nem muito curto, nem muito longo) +- Implemente refresh tokens para melhor experiĆŖncia do usuĆ”rio +- Use rate limiting para prevenir ataques de forƧa bruta +- Monitore tentativas de login falhadas +- Implemente logout do lado do servidor (blacklist de tokens) + +### šŸ›”ļø **ProteƧƵes Contra Ataques** +- **ForƧa Bruta**: Senhas hasheadas com BCrypt (lento por design) +- **Token Replay**: Tokens expiram após tempo configurado +- **Token Forgery**: Assinatura HMAC-SHA256 com chave secreta +- **SQL Injection**: SQLAlchemy ORM com queries parametrizadas +- **XSS**: FastAPI serializa automaticamente respostas JSON + +--- + +## šŸ“š **REFERÊNCIAS** + +### **Documentação Relacionada** +- [PERMISSIONS.MD](PERMISSIONS.MD) - Sistema de permissƵes RBAC +- [FLUXOGRAMA.MD](FLUXOGRAMA.MD) - Fluxo geral da aplicação +- [README.MD](../README.MD) - Documentação principal do projeto + +### **Bibliotecas Utilizadas** +- [FastAPI Security](https://fastapi.tiangolo.com/tutorial/security/) +- [python-jose](https://python-jose.readthedocs.io/) +- [bcrypt](https://pypi.org/project/bcrypt/) +- [OAuth2 Specification](https://oauth.net/2/) +- [JWT.io](https://jwt.io/) - Decoder de tokens JWT + +### **EspecificaƧƵes** +- [RFC 7519 - JWT](https://datatracker.ietf.org/doc/html/rfc7519) +- [RFC 6749 - OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc6749) +- [BCrypt Algorithm](https://en.wikipedia.org/wiki/Bcrypt) + +--- + +## šŸ’” **PERGUNTAS FREQUENTES** + +### **1. Quanto tempo o token dura?** +Por padrĆ£o, 30 minutos. ConfigurĆ”vel via `SECURITY_ACCESS_TOKEN_EXPIRE_MINUTES` no `.env`. + +### **2. O que acontece quando o token expira?** +O usuĆ”rio recebe um erro 401 e precisa fazer login novamente para obter um novo token. + +### **3. Posso ter mĆŗltiplos tokens ativos?** +Sim, cada login gera um novo token. Todos permanecem vĆ”lidos atĆ© expirarem. + +### **4. Como faƧo logout?** +Atualmente, o logout Ć© feito no lado do cliente (descartando o token). Para logout do servidor, seria necessĆ”rio implementar uma blacklist de tokens. + +### **5. Posso renovar um token sem fazer login novamente?** +NĆ£o, atualmente. Para implementar isso, seria necessĆ”rio adicionar refresh tokens ao sistema. + +### **6. Qual a diferenƧa entre autenticação e autorização?** +- **Autenticação**: Verifica QUEM vocĆŖ Ć© (login com usuĆ”rio/senha, validação de token) +- **Autorização**: Verifica O QUE vocĆŖ pode fazer (permissƵes via RBAC) + +### **7. Por que BCrypt ao invĆ©s de SHA256?** +BCrypt Ć© especificamente projetado para senhas, sendo intencionalmente lento para dificultar ataques de forƧa bruta, alĆ©m de incluir salt automaticamente. + +### **8. O token pode ser decodificado por qualquer um?** +O token pode ser decodificado (payload Ć© base64), mas nĆ£o pode ser MODIFICADO sem a chave secreta. A assinatura garante que o token nĆ£o foi adulterado. + +--- + +## šŸ“ž **SUPORTE** + +Para dĆŗvidas ou problemas com autenticação: +- Abra uma issue no GitHub +- Consulte a documentação do FastAPI +- Revise os logs da aplicação +- Verifique as configuraƧƵes do `.env` e `.secrets` + +--- + +**Última atualização**: Dezembro 2024 +**VersĆ£o da Documentação**: 1.0 diff --git a/README.MD b/README.MD index 9e7fcd9..9fba73b 100644 --- a/README.MD +++ b/README.MD @@ -114,6 +114,15 @@ Para informaƧƵes tĆ©cnicas detalhadas sobre o projeto, consulte os documentos ### šŸ“Š **Modelo de Entidades e Relacionamentos** - **Diagrama ER**: [DOCS/MODELS.png](DOCS/MODELS.png) - Visualização completa das entidades e seus relacionamentos no banco de dados. +### šŸ” **Sistema de Autenticação (JWT)** +- **Guia Completo**: [DOCS/AUTHENTICATION.MD](DOCS/AUTHENTICATION.MD) - Documentação detalhada sobre: + - Fluxo de autenticação com JWT + - Como obter e usar tokens de acesso + - Estrutura e validação de tokens JWT + - SeguranƧa de senhas com BCrypt + - Integração com o sistema de autorização + - CenĆ”rios prĆ”ticos e exemplos de código + ### šŸ” **Sistema de PermissƵes (RBAC)** - **Guia Completo**: [DOCS/PERMISSIONS.MD](DOCS/PERMISSIONS.MD) - Documentação detalhada sobre: - Como um usuĆ”rio novo ganha permissƵes From 7839b77348068a892b97524188f359e54a8473e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:43:37 +0000 Subject: [PATCH 3/3] Fix documentation style and consistency issues Co-authored-by: jvras58 <48683351+jvras58@users.noreply.github.com> --- DOCS/AUTHENTICATION.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DOCS/AUTHENTICATION.MD b/DOCS/AUTHENTICATION.MD index c79070a..2b43247 100644 --- a/DOCS/AUTHENTICATION.MD +++ b/DOCS/AUTHENTICATION.MD @@ -47,7 +47,7 @@ sequenceDiagram POST /auth/token Content-Type: application/x-www-form-urlencoded -username=seu_usuario&password=sua_senha +username=admin&password=senha123 ``` ### **2. Usando cURL** @@ -336,7 +336,7 @@ curl -X POST "http://localhost:8000/users/" \ "password": "senha123" }' -# āš ļø IMPORTANTE: UsuĆ”rio criado nĆ£o tem NENHUMA permissĆ£o +# āš ļø IMPORTANTE: UsuĆ”rio criado nĆ£o tem nenhuma permissĆ£o # Um admin precisa atribuir um Role via Assignment ```