Pular para conteúdo

Aula 18 - Autenticação Segura (OAuth2, OpenID Connect e JWT) 🔐

Objetivo Pedagógico

Objetivo: Arquitetura de autenticação e autorização stateless com tokens JWT assinados com RSA/ECDSA, fluxo OAuth 2.1 Authorization Code com PKCE e OpenID Connect.


📑 1. Fundamentos Teóricos & Análise Técnica

A segurança em ecossistemas de APIs modernas requer desacoplamento estrito entre o provedor de identidade e os serviços consumidores. O padrão de indústria consolidado fundamenta-se na tríade: 1. OAuth 2.1: Framework de autorização delegado que concede a aplicações clientes acesso restrito a recursos em nome do proprietário. O fluxo moderno obrigatório para SPAs e apps móveis é o Authorization Code Flow com PKCE (Proof Key for Code Exchange), eliminando o inseguro fluxo implícito (Implicit Grant). 2. OpenID Connect (OIDC): Camada de identidade construída sobre o OAuth 2.0 que padroniza o ID Token, permitindo que o cliente verifique a identidade do usuário final e obtenha seu perfil básico através do endpoint /userinfo. 3. JSON Web Tokens (JWT - RFC 7519): Estrutura compacta e autocontida codificada em Base64URL composta por Header, Payload e Signature.

Boas práticas críticas de segurança com JWT: - Assinatura assimétrica obrigatória com chaves públicas/privadas (RS256 ou ES256), permitindo que microsserviços validem tokens localmente sem consultar o servidor de autenticação a cada requisição. - Tokens de acesso (Access Tokens) com tempo de vida efêmero (5 a 15 minutos). - Rotação segura de Refresh Tokens armazenados exclusivamente em cookies HttpOnly; Secure; SameSite=Strict.

📐 Arquitetura Conceitual & Diagrama de Fluxo

sequenceDiagram
    autonumber
    actor U as Usuário / SPA
    participant AuthServer as Authorization Server (OIDC)
    participant Gateway as API Gateway / Backend

    U->>AuthServer: 1. Login com PKCE (Code Challenge)
    AuthServer-->>U: 2. Authorization Code
    U->>AuthServer: 3. Troca Code + Code Verifier
    AuthServer-->>U: 4. Emite Access Token (JWT) + Refresh Token
    U->>Gateway: 5. Requisição HTTP (Header: Authorization Bearer <JWT>)
    Note over Gateway: 6. Validação Criptográfica Local com Chave Pública (JWKS)
    Gateway-->>U: 7. Resposta Autorizada (200 OK)

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Autenticação Stateless: Nenhuma sessão mantida em memória no backend; a assinatura criptográfica atesta a integridade do token. - Fluxo PKCE Mandatório: Prevenção contra interceptação de código de autorização em clientes públicos. - Chaves Públicas via JWKS: Exposição de chaves públicas rotacionáveis no endpoint /.well-known/jwks.json. - Defesa em Profundidade: Validação estrita de claims (exp, iss, aud) em todas as chamadas de API.


🛠️ 2. Implementação Prática em Segurança em APIs, OAuth 2.1 e JWT

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// jwt-verifier.ts (Validação Criptográfica de JWT com JWKS)
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';

const client = jwksClient({
  jwksUri: 'https://auth.empresa.com/.well-known/jwks.json',
  cache: true,
  rateLimit: true,
  jwksRequestsPerMinute: 10
});

function getKey(header: jwt.JwtHeader, callback: jwt.SigningKeyCallback) {
  client.getSigningKey(header.kid, (err, key) => {
    if (err) return callback(err);
    const signingKey = key?.getPublicKey();
    callback(null, signingKey);
  });
}

export function verifyAccessToken(token: string): Promise<jwt.JwtPayload> {
  return new Promise((resolve, reject) => {
    jwt.verify(
      token,
      getKey,
      {
        audience: 'https://api.empresa.com',
        issuer: 'https://auth.empresa.com/',
        algorithms: ['RS256']
      },
      (err, decoded) => {
        if (err) return reject(new Error(`Token Inválido: ${err.message}`));
        resolve(decoded as jwt.JwtPayload);
      }
    );
  });
}

💡 Análise Passo a Passo do Código

  1. Integração JWKS: O cliente jwksClient obtém a chave pública correspondente ao kid (Key ID) do cabeçalho do token em cache.
  2. Validação de Claims: audience e issuer são estritamente verificados para impedir que tokens emitidos para outros serviços sejam aceitos.
  3. Algoritmo RS256 Assimétrico: A chave privada nunca sai do Authorization Server; os microsserviços usam apenas a chave pública.

🎯 3. Próximos Passos & Sequência Didática