Origens: autorização nunca foi feita para logar ninguém

O foi escrito para um problema específico, e identidade não era ele. Por volta de 2007 o padrão para conectar um serviço a outro era compartilhar senha: o usuário entregava a um site as credenciais do e-mail para que ele lesse os contatos. O OAuth 1.0 existiu para acabar com isso - para deixar uma aplicação obter acesso delegado a um recurso sem receber a senha do usuário.

O OAuth 2.0 ( 6749, 2012) simplificou e generalizou, e diz isso com todas as letras: é um arcabouço de autorização. Não tem forma definida de dizer quem é o usuário, nem formato padrão de identificador, nem prova exigida de quando ou como o usuário se autenticou.

Isso não impediu ninguém. Os provedores construíram login em cima assim mesmo, cada um de um jeito, e a era dos fluxos proprietários de "entrar com" produziu a classe previsível de vulnerabilidades - com destaque para o delegado confuso: um token de acesso prova que uma aplicação pode chamar uma API, não quem está no teclado, então uma aplicação que aceita token como prova de identidade pode receber um token obtido em outro lugar, de outro usuário, e ser enganada.

O OpenID Connect (2014) é a correção. É uma camada fina de identidade sobre o OAuth 2.0, e não um substituto: mesmos endpoints, mesmos fluxos, mais as peças de que a autenticação precisa - um ID token como assinado com claims definidas, um endpoint UserInfo, um documento de descoberta numa URL conhecida, e chaves de assinatura publicadas.

A linhagem importa porque explica o formato: o não redesenhou nada. Acrescentou a afirmação que faltava - este usuário se autenticou, neste horário, por este método, neste emissor, para esta audiência - a um protocolo que a deixara de fora de propósito.

Duas perguntas, não uma

OAuth 2.0 e OpenID Connect são constantemente confundidos, em parte porque o OIDC (OpenID Connect) é construído sobre o OAuth e eles compartilham endpoints e terminologia. A forma mais limpa de separá-los é notar que eles respondem a perguntas diferentes. O OAuth 2.0 responde a uma pergunta de autorização: esta aplicação tem permissão para acessar aquele recurso em nome do usuário. O OpenID Connect responde a uma pergunta de autenticação: quem é o usuário que acabou de entrar. Um é sobre permissão para agir; o outro é sobre identidade. O OIDC coloca a resposta de identidade sobre a maquinaria de permissão do OAuth.

Access token versus ID token

A expressão mais clara da diferença são os dois tipos de token, e tratá-los como intercambiáveis é o erro mais comum e mais perigoso.

Um access token é uma credencial para chamar uma API. Ele representa uma permissão delegada, e a aplicação deve enviá-lo a um servidor de recursos, que o verifica e atende à requisição. Para a aplicação cliente, um access token é frequentemente opaco: o cliente não é a audiência pretendida e não deveria interpretá-lo nem tomar decisões a partir de seu conteúdo. Seu significado pertence ao servidor de recursos.

Um ID token é uma declaração sobre o usuário, emitida pelo provedor para o cliente. O cliente é a audiência pretendida, e o cliente deve lê-lo, validá-lo e descobrir quem é o usuário. É sempre um JWT com um conjunto definido de claims. A claim de audiência é o indício: a audiência de um ID token é o cliente, enquanto a audiência de um access token (quando ele tem uma) é o servidor de recursos. Usar um access token para decidir quem é o usuário, ou entregar um ID token a uma API como se fosse um access token, são ambos erros de categoria que levam a vulnerabilidades reais.

Por que OAuth puro não é um protocolo de login

Antes de o OIDC existir, muitas aplicações implementaram "entrar com o provedor X" usando OAuth 2.0 puro, e o padrão persiste em alguns lugares. A aplicação obtinha um access token e tratava a capacidade de obtê-lo, ou o resultado de chamar alguma API de informações de usuário com ele, como prova de quem o usuário era. Isto é um antipadrão conhecido, e a razão é sutil mas importante: um access token não diz nada confiável sobre quem o solicitou nem para quem foi emitido. Um token obtido por uma aplicação pode, em algumas configurações, ser apresentado por outra, e uma aplicação que infere identidade pela mera posse de um access token pode ser enganada e fazer login com o usuário errado. Isso às vezes é chamado de problema do delegado confuso.

O OIDC foi projetado para fechar exatamente essa lacuna. O ID token é endereçado explicitamente a um cliente específico por sua claim de audiência, é vinculado a uma tentativa de login específica por seu nonce, e é assinado pelo provedor para que não possa ser forjado. Essas são precisamente as propriedades que faltam a um access token e que a autenticação exige. A regra prática é simples: não construa login sobre OAuth puro. Se você precisa saber quem é o usuário, use o OpenID Connect e valide o ID token.

As claims que fazem o trabalho

Um ID token só serve se for validado, e a validação é o protocolo:

  • iss - o emissor, conferido contra o que você configurou, e não contra o que o token diz ser.
  • aud - a audiência, que precisa ser o identificador do seu cliente. É esta a conferência que impede o delegado confuso.
  • exp e iat - expiração e emissão, com tolerância para desvio de relógio.
  • nonce - amarrada ao valor que a sua aplicação enviou, o que impede um token de ser reproduzido em outra sessão.
  • sub - o identificador estável do usuário naquele emissor. Não é o e-mail, que muda e pode ser reatribuído; o par de fato estável é emissor mais sujeito.
  • auth_time, acr, amr - quando o usuário se autenticou e por qual meio, que é como uma aplicação exige login recente ou mais forte para uma ação sensível.

E a assinatura, verificada contra as chaves publicadas do emissor, com a rotação de chaves que isso implica.

Os fluxos, e quais ainda estão corretos

  • Código de autorização com - a resposta atual para todo tipo de cliente, navegador ou nativo. O PKCE nasceu como correção para móvel e hoje é recomendado universalmente, porque amarra o código ao cliente que o pediu.
  • Fluxo implícito - devolvia tokens direto pelo navegador. Depreciado: token em URL termina em histórico, log e referrer.
  • Credenciais do dono do recurso - o usuário entrega a senha à aplicação. Retirado das recomendações atuais, já que recria exatamente o problema que o OAuth foi inventado para resolver.
  • Credenciais de cliente - sem usuário nenhum, de serviço para serviço. Correto, e fora da questão de identidade.
  • Autorização de dispositivo - para equipamentos com entrada limitada, em que o usuário se autentica numa segunda tela.

O logout por canal frontal e por canal traseiro é a parte que a maioria das implantações pula, e a razão de um usuário que sai de uma aplicação seguir logado em outras cinco.

O ecossistema, por categoria

  • Provedores de identidade - Okta, Microsoft Entra, Ping Identity, Auth0, Google, e o Keycloak de código aberto. O que difere entre eles raramente é o protocolo, que é bem especificado; é administração, tempo de vida de token, tratamento de sessão e como federam.
  • Bibliotecas - a orientação honesta é usar uma certificada em vez de montar a validação sozinho, porque cada passo da lista acima é um lugar onde uma implementação plausível é silenciosamente insegura.
  • Gateways de API e proxies, que validam tokens na borda para que os serviços atrás não reimplementem cada um.
  • O programa de certificação da OpenID Foundation, que é o jeito prático de saber que uma implementação de fato está conforme, e não apenas interopera num dia bom.

O segue difundido em ambientes corporativos e de educação, e a escolha entre os dois costuma ser institucional, e não técnica: SAML onde a contraparte é uma federação corporativa estabelecida, OIDC onde os clientes são aplicativos móveis e APIs modernas. Os dois autenticam; diferem em codificação, em transporte e em quanto envolvem o navegador.

Como distingui-los na prática

Quando você tem um token em mãos e não sabe ao certo qual é, alguns sinais ajudam. Se ele decodifica como um JWT com iss, sub, aud, exp e iat, e a audiência é o seu identificador de cliente, é um ID token; o decodificador OIDC o reconhecerá e interpretará as claims. Um access token pode ser opaco (não um JWT de forma alguma), ou pode ser um JWT cuja audiência é um servidor de recursos e cujas claims descrevem escopos e permissões em vez de identidade do usuário. A presença do escopo openid na requisição original é o que fez com que um ID token fosse emitido em primeiro lugar. Na dúvida, decodifique o token e olhe a audiência e as claims: elas dizem para que o token serve, e portanto como ele deve ser usado.

Esta série, em ordem

Este artigo abre a série OAuth e OpenID Connect. Ele separa os dois trabalhos constantemente confundidos; as partes constroem primeiro o OAuth (o fluxo de código, quem consegue guardar um segredo, o PKCE, os tokens, o grant a escolher) e depois a camada de identidade sobre ele (o que o OpenID Connect acrescenta, seu fluxo, as claims que uma relying party verifica e como um provedor se descreve).

  1. O fluxo de código de autorização do OAuth 2.0. Os quatro papéis, o redirecionamento e a troca, e por que o código é trocado por um token no canal de retaguarda.
  2. Clientes públicos vs confidenciais, e onde o PKCE se encaixa. Se um cliente consegue guardar um segredo decide seu modelo de segurança, e por que aplicações de página única e móveis são clientes públicos.
  3. PKCE: como proteger o fluxo de código de autorização do OAuth. O ataque de interceptação que o PKCE derrota, o verifier e o challenge, e por que o S256 é obrigatório.
  4. Tokens de acesso, tokens de atualização e tokens de ID. Tokens de acesso, de atualização e de ID, para que serve cada um, e o defeito real de mandar um onde cabe outro.
  5. Fluxos OAuth: como escolher o grant em 2026. Código com PKCE para pessoas, client credentials para máquinas, o device grant para televisores, e por que o grant implicit foi aposentado.
  6. OpenID Connect: uma camada de identidade sobre o OAuth 2.0. A camada de identidade: o ID token no centro, os papéis de relying party e de provedor, e por que um ID token é um JWT.
  7. O fluxo authorization code do OIDC. Como uma aplicação recebe um ID token: o login no provedor, o código de vida curta, a troca no canal de retaguarda.
  8. As claims do ID token, e o que uma relying party verifica. iss, sub, aud, exp e iat, o nonce que impede a repetição, azp, acr e amr: o que uma relying party verifica.
  9. OIDC Discovery: o documento openid-configuration. O documento .well-known/openid-configuration: endpoints, jwks_uri, algoritmos de assinatura, aprendidos automaticamente.