OAuth explicado: papéis, fluxo PKCE e OAuth vs SAML
OAuth explicado
O que é OAuth? Papéis, fluxo PKCE, OAuth vs SAML vs OIDC | We.Inc
OAuth 2.0 em palavras simples: os quatro papéis, o fluxo authorization code com PKCE passo a passo, scopes e como o OAuth se diferencia do OpenID Connect e do SAML.
OAuth 2.0 é um padrão que permite a um app agir em seu nome em outro serviço sem nunca ver sua senha. Você aprova um pedido na própria página de login do serviço, e o app recebe um access token limitado aos scopes que você autorizou. Ele cuida da autorização; o OpenID Connect adiciona o login por cima.
OAuth 2.0 vs OpenID Connect vs SAML 2.0
OAuth 2.0
OpenID Connect
SAML 2.0
Responde
O que este app pode acessar?
Quem é este usuário?
Quem é este usuário?
Artefato principal
Access token
ID token (um JWT) mais access token
Asserção XML
Especificação
RFC 6749 (IETF)
OpenID Connect Core 1.0
OASIS SAML 2.0
Partes
Cliente, servidor de autorização, servidor de recursos
Relying party, provedor OpenID
Provedor de serviço, provedor de identidade
Uso típico
Acesso a APIs, "conecte sua conta"
Botões "Entrar com", login em apps mobile e SPAs
Single sign-on corporativo
Antes do OAuth, conectar dois serviços muitas vezes significava digitar a senha de um no outro. O OAuth trocou isso por tokens de curta duração e escopo restrito, emitidos só depois da sua aprovação. O gerador abaixo cria um verifier e um challenge PKCE reais no seu navegador e monta a URL de autorização, para você ver cada parâmetro que o fluxo usa.
O app cria um code_verifier aleatório, gera o hash dele em um code_challenge e envia você ao servidor de autorização com esse challenge, o client_id, os scopes e um valor de state.
Você faz login na página do servidor de autorização e aprova os scopes.
O servidor redireciona de volta para o redirect_uri do app com um authorization code de curta duração e o mesmo state.
O app confere o state e depois envia por POST o code e o code_verifier original para o token endpoint.
O servidor gera o hash do verifier, compara com o challenge guardado e retorna um access token que o app envia para a API.
Use o fluxo authorization code com PKCE tanto em single-page apps quanto em apps mobile e apps de servidor.
Sempre envie e confira o state, que a especificação do OAuth recomenda para evitar cross-site request forgery.
Peça os scopes mais restritos que resolvam o problema; as pessoas aprovam pedidos pequenos com mais facilidade.
Registre redirect URIs exatas. Curingas e open redirects são uma forma clássica de roubar tokens.
Mantenha os client secrets só no servidor. Um app de navegador ou mobile não consegue guardar um segredo.
Perguntas frequentes
OAuth é autenticação ou autorização?
Autorização. Um access token diz o que um app pode fazer, não quem é o usuário, e as APIs podem nem informar isso. Quando você precisa da identidade da pessoa, use o OpenID Connect, que retorna um ID token assinado com claims como sub, iss, aud e exp.
O que é PKCE e eu preciso dele?
O PKCE (RFC 7636) vincula o authorization code ao app que iniciou o fluxo. O app envia primeiro o hash de um segredo aleatório e depois o próprio segredo, então um code roubado não serve para nada. Use S256, que os servidores são obrigados a suportar, em vez de plain.
Qual é a diferença entre OAuth e SAML?
SAML é um padrão mais antigo, baseado em XML, em que um provedor de identidade envia uma asserção assinada sobre o usuário para um provedor de serviço, principalmente para single sign-on corporativo no navegador. O OAuth emite tokens para acesso a APIs e funciona bem para apps mobile e APIs. O OpenID Connect é o equivalente mais próximo, no mundo OAuth, do login com SAML.
O que são scopes?
Scopes são as permissões que um app pede, escritas como uma lista de strings separadas por espaço, que diferenciam maiúsculas de minúsculas e são definidas pelo servidor de autorização, por exemplo openid email ou repo read:user. A tela de consentimento mostra esses scopes, e o token só cobre o que foi aprovado.
Ainda devo usar o fluxo implicit?
Não em projetos novos. Ele retornava os tokens no fragmento da URL, onde podem vazar pelo histórico e pelos logs. O fluxo authorization code com PKCE dá aos apps de navegador a mesma praticidade sem essa exposição.
Os quatro papéis
A RFC 6749 define quatro partes. O dono do recurso é você. O cliente é o app que pede acesso. O servidor de autorização confere quem você é e emite tokens. O servidor de recursos hospeda a API que aceita esses tokens. Muitas vezes uma mesma empresa roda os dois servidores, mas são funções separadas.
Por que existe a troca do code
O redirecionamento de volta para o app passa pelo navegador, um lugar onde qualquer coisa valiosa pode vazar. Por isso o redirecionamento carrega só um code de uso único, que a especificação recomenda expirar em até 10 minutos. O token de verdade é buscado em uma chamada direta ao token endpoint.
O PKCE fecha a brecha que sobra. Mesmo que um malware ou um proxy que registra tráfego capture o code, ele não consegue resgatá-lo sem o verifier, que nunca saiu do app.
Onde entra o OpenID Connect
O OpenID Connect é uma camada fina sobre o OAuth. Adicione openid aos scopes, o que a especificação do OIDC torna obrigatório, e a resposta do token também traz um ID token: um JWT assinado que descreve o usuário. Um nonce enviado no pedido e repetido no ID token protege contra replay.
O fluxo authorization code com PKCE
Cada etapa e os parâmetros que ela carrega
Etapa
De para
Parâmetros principais
1. Pedido de autorização
App para servidor de autorização (redirecionamento do navegador)
access_token, token_type, expires_in, refresh_token opcional (e id_token com OIDC)
6. Chamada à API
App para servidor de recursos
Authorization: Bearer <access_token>
PKCE em código
Criar um verifier e um challenge S256 no navegador
32 bytes aleatórios codificados em base64url geram um verifier de 43 caracteres, o menor tamanho que a RFC 7636 permite.
Trocar o code por tokens
Roda depois do redirecionamento. Compare o state primeiro e depois envie o verifier guardado junto com o code.
Gerador de PKCE e URL de autorização
Cria um code_verifier novo e o code_challenge S256 dele com a criptografia do seu navegador e depois monta uma URL de autorização a partir das suas configurações. Nada é enviado; o endpoint abaixo é um exemplo que você substitui.
Endpoint de autorização
Scopes (separados por espaço)
Novo verifier
code_verifier ({n} caracteres, mantenha em segredo até a etapa 4)