OpenID Connect: autenticação sobre OAuth
1. Fundamentos do OpenID Connect (OIDC)
O OpenID Connect (OIDC) é uma camada de identidade construída sobre o protocolo OAuth 2.0. Enquanto o OAuth 2.0 foi projetado para autorizar o acesso a recursos (permitir que um aplicativo acesse APIs em nome do usuário), o OIDC adiciona autenticação — a capacidade de verificar quem é o usuário.
A diferença fundamental é:
- OAuth 2.0: "Este aplicativo pode acessar seus arquivos no Drive?"
- OIDC: "Qual é a identidade do usuário que está usando este aplicativo?"
Os papéis no fluxo OIDC são:
- RP (Relying Party): o aplicativo que deseja autenticar o usuário (seu frontend ou backend)
- OP (OpenID Provider): o servidor de autenticação (Google, Auth0, Keycloak)
- End-User: o usuário humano que está sendo autenticado
2. O Token ID (id_token) e sua estrutura
O coração do OIDC é o id_token, um JWT (JSON Web Token) que contém claims sobre a identidade do usuário. Sua estrutura típica:
{
"iss": "https://accounts.google.com",
"sub": "1234567890",
"aud": "seu-client-id.apps.googleusercontent.com",
"exp": 1718000000,
"iat": 1717996400,
"nonce": "a1b2c3d4e5f6",
"name": "João Silva",
"email": "joao@exemplo.com",
"preferred_username": "joaosilva"
}
Claims obrigatórias que todo id_token deve conter:
iss(issuer): quem emitiu o tokensub(subject): identificador único do usuário no OPaud(audience): o client_id do seu aplicativoexp(expiration): timestamp de expiraçãoiat(issued at): timestamp de emissão
Nonce: um valor aleatório gerado pelo RP e enviado na requisição de autenticação. O OP deve incluí-lo no id_token. Isso protege contra:
- Replay attacks: um token interceptado não pode ser reutilizado
- Fixação de sessão: o nonce vincula a autenticação a uma sessão específica do RP
3. Fluxos de Autenticação no OIDC
Authorization Code Flow (com PKCE)
O fluxo mais seguro, especialmente para aplicações públicas (SPA, mobile). O código de autorização nunca é exposto ao navegador do usuário.
1. RP gera code_verifier (string aleatória) e code_challenge = SHA256(code_verifier)
2. Navegador → OP: /authorize?response_type=code&client_id=...&code_challenge=...
3. Usuário autentica no OP
4. OP → Navegador: redirect com ?code=xyz
5. Navegador → RP: envia o code
6. RP → OP: /token?code=xyz&code_verifier=... (troca segura do código por tokens)
7. OP → RP: access_token + id_token + refresh_token
PKCE (Proof Key for Code Exchange) é obrigatório para apps públicos. Sem PKCE, um atacante que intercepte o authorization code pode trocá-lo por tokens.
Implicit Flow (DESCONTINUADO)
Neste fluxo, o id_token era retornado diretamente na URL de redirect:
https://meuapp.com/callback#id_token=eyJhbGciOiJSUzI1NiIs...
Riscos: o token fica visível no histórico do navegador, logs de proxy, e pode ser vazado pelo Referer header. Nunca use este fluxo — foi descontinuado pelo IETF.
Hybrid Flow
Combina elementos dos fluxos Authorization Code e Implicit. Pode retornar id_token + code na primeira resposta. Útil quando o RP precisa do id_token imediatamente, mas aumenta a superfície de ataque porque parte do token trafega pela URL.
4. Validação e Segurança do id_token
Validar o id_token é crítico para segurança. Um token malicioso pode comprometer todo o sistema.
Verificação de assinatura
Algoritmos ACEITÁVEIS:
- RS256 (RSA com SHA-256) — mais comum
- ES256 (ECDSA com P-256) — mais eficiente
Algoritmos PROIBIDOS:
- none — token sem assinatura (atacante pode forjar qualquer identidade)
- HS256 com chave pública — se a chave para HMAC for pública, qualquer um pode criar tokens válidos
Validação de claims
aud: deve ser EXATAMENTE seu client_id
iss: deve ser o emissor esperado (lista branca)
exp: token não pode estar expirado (com margem de tolerância, ex: 5 min)
iat: token não pode ter sido emitido no futuro
nonce: deve corresponder ao valor que você enviou
Proteção contra substituição de token
Se um atacante obtém um id_token válido de outro cliente (com aud diferente), ele pode tentar usá-lo no seu sistema. A validação de aud bloqueia isso.
A claim azp (authorized party) deve ser verificada quando o aud contiver múltiplos valores — indica qual cliente realmente usou o token.
5. UserInfo Endpoint e Claims Adicionais
O UserInfo Endpoint é uma API protegida do OP que retorna claims sobre o usuário. Use-o quando:
- O id_token não contém claims suficientes
- Você precisa de claims atualizadas (o id_token pode expirar)
- A política de privacidade exige chamadas autenticadas
GET /userinfo HTTP/1.1
Authorization: Bearer <access_token>
Atenção: use o access_token para chamar o UserInfo, nunca o id_token. O id_token é apenas para verificação de identidade, não para autorização.
Escopos OIDC
openid — obrigatório, ativa o fluxo OIDC
profile — name, family_name, preferred_username, picture
email — email, email_verified
address — endereço postal
phone — phone_number, phone_number_verified
Perigo de escopos excessivos: solicitar profile quando você só precisa do email expõe dados desnecessários. Se o vazamento ocorrer, sua responsabilidade aumenta. Solicite apenas o mínimo necessário.
6. Logout Seguro (Single Logout - SLO)
RP-Initiated Logout
O RP inicia o logout redirecionando o usuário para o OP:
GET /logout?id_token_hint=eyJhbGciOiJSUzI1NiIs...
&post_logout_redirect_uri=https://meuapp.com/logout
&state=xyz
O parâmetro id_token_hint ajuda o OP a identificar qual sessão encerrar. Sem ele, o OP pode não conseguir associar a requisição a uma sessão ativa.
Session Management via iframe
O OP pode expor um endpoint check_session_iframe que permite ao RP monitorar o estado da sessão no OP via postMessage. Riscos: vulnerável a clickjacking se não usar headers X-Frame-Options: DENY ou Content-Security-Policy: frame-ancestors 'none'.
Riscos de logout incompleto
- O access_token pode continuar válido mesmo após o logout — implemente uma lista de revogação ou use tokens de curta duração
- A sessão do OP pode não ser encerrada — o usuário ainda está logado no Google, por exemplo
- SLO (Single Logout): garanta que o OP notifique todos os RPs sobre o logout, mas lembre-se que isso é difícil em ecossistemas heterogêneos
7. Ameaças Comuns e Mitigações
Ataque de confusão de provedor
O atacante faz o RP aceitar tokens de um OP malicioso. Mitigação: valide rigorosamente o iss contra uma lista branca de emissores confiáveis. O JWKS URI (jwks_uri) também deve vir de um domínio conhecido.
Mix-up attack
O atacante confunde o RP sobre qual OP está sendo usado, fazendo o RP enviar o código de autorização para o OP errado. Mitigação: use redirect_uri fixo (um único URI por client_id) e valide o parâmetro state para associar a resposta à requisição original.
Roubo de authorization code
Sem PKCE, um atacante pode roubar o código de autorização (via malware no dispositivo do usuário, por exemplo) e trocá-lo por tokens. Mitigação: PKCE é obrigatório para apps públicos (SPA, mobile, desktop).
Cross-Site Request Forgery (CSRF)
O atacante força o usuário a iniciar um fluxo de autenticação sem seu conhecimento. Mitigação: use state e nonce. O state protege contra CSRF no redirect, e o nonce protege contra replay do id_token.
Resumo de boas práticas:
- Sempre use Authorization Code Flow + PKCE
- Valide assinatura do id_token (nunca aceite 'alg: none')
- Verifique aud, iss, exp, nonce
- Use escopos mínimos necessários
- Implemente logout completo com revogação de tokens
- Mantenha uma lista branca de emissores confiáveis
Referências
- OpenID Connect Specification (Core) — Documentação oficial do protocolo OIDC, definindo todos os fluxos e claims
- OAuth 2.0 for Browser-Based Applications (Best Current Practice) — Recomendações de segurança para SPAs, incluindo PKCE e proibição do Implicit Flow
- JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens — Especificação sobre o uso de JWTs como access tokens, complementar ao OIDC
- OpenID Connect Session Management — Especificação oficial sobre gerenciamento de sessão e logout no OIDC
- OAuth 2.0 Threat Model and Security Considerations — Documento abrangente sobre ameaças e mitigações em OAuth 2.0 e OIDC
- Auth0 - OpenID Connect Handbook — Guia prático sobre implementação de OIDC com exemplos de código
- Keycloak - OpenID Connect Documentation — Documentação oficial do Keycloak sobre configuração de OIDC