O OpenID Connect define como uma aplicação de fato obtém um ID token, e o fluxo para o qual ele o direciona é o fluxo authorization code. É uma dança de redirects com uma divisão deliberada entre o que viaja pelo navegador e o que não viaja.
Os passos
- A aplicação (o relying party) redireciona o usuário ao authorization endpoint do provedor de identidade, com parâmetros:
client_id, umredirect_uri,scope=openid(mais quaisquer outros),response_type=code, um valorstate, e umnonce. - O usuário se autentica no provedor e consente. A aplicação não se envolve nisso; ela nunca vê as credenciais.
- O provedor redireciona o navegador de volta para o
redirect_uricom um código de autorização de curta duração na URL. - A aplicação pega esse código e, por uma chamada de back-channel direta ao token endpoint, o troca (autenticando-se com um client secret ou ) por um ID token e normalmente um access token.
- A aplicação valida o ID token: sua assinatura, issuer, audience, expiração, e que o
noncecorresponde ao que ela enviou.
Por que o código, e não o token, volta
A razão para a troca em duas etapas é que o código de autorização é quase inútil sozinho. Mesmo que alguém o intercepte da URL, não consegue resgatá-lo sem a chamada de back-channel e a autenticação do cliente. Compare com o antigo fluxo implicit, que retornava o token diretamente na URL do navegador, onde ele poderia vazar por histórico, referrers ou logs. O implicit agora é desencorajado exatamente por isso, e o fluxo code é preferido em todo lugar.
state, nonce e PKCE
Três parâmetros fazem o trabalho pesado de segurança. O state amarra a resposta de volta à requisição que a aplicação iniciou, derrotando cross-site request forgery no callback. O nonce é ecoado dentro do ID token para que a aplicação possa confirmar que o token responde à sua requisição e não é um replay. O PKCE adiciona uma prova de uso único para que até um cliente público sem segredo (um app single-page ou mobile) possa provar que é a mesma parte que iniciou o fluxo. Juntos eles tornam a dança de redirects segura para rodar em um navegador, que é por que o fluxo authorization code com PKCE é o padrão moderno.
state e nonce defendem ataques diferentes, e um não é dois
São frequentemente implementados como se qualquer um satisfizesse o requisito. Eles não se sobrepõem.
state amarra o redirecionamento à sessão de navegador que o iniciou. Sem ele, um atacante completa a própria autorização e faz o navegador da vítima entregar o código resultante — a vítima acaba logada na conta do atacante, o que é silencioso, confuso, e pior do que parece quando aquela conta passa a coletar o que a vítima envia.
nonce amarra o ID token àquela mesma requisição, para que um token emitido num login não seja reproduzido em outro.
Implementar um e supor o outro coberto deixa um ataque inteiro aberto, e nenhuma das falhas produz erro — o fluxo completa, o usuário entra, e o único sinal é que entrou como outra pessoa.