Extensão PKCE do Authorization Code para aplicações SPA ou Mobile
A extensão PKCE é utilizada no fluxo do authorization code para garantir que aplicações SPA, Mobile ou qualquer outro tipo de aplicação que não consiga garantir que o seu client secret se mantenha em segredo, consigam autenticar seus usuários em segurança.
Como o PKCE garante a segurança do fluxo?
Em alguns cenários de aplicações client side é possível observar alguns ataques onde individuos mal intencionados consigam acesso ao code retornado pelo Identity, neste caso, se esses individuos obtiverem acesso ao client secret da aplicação interceptada, é possivel obter o access token no lugar da aplicação.
Para garantir que somente a aplicação legítima consiga obter o access token através do authorization code retornado pelo Identity, a extensão do PKCE adiciona três novos parâmetros no fluxo do authorization code que tornam essa comunicação mais segura.
- code_verifier
- code_challenge
- code_challenge_method
code_verifier
Um hash criptográficamente aleatório que será utilizado para correlacionar os requests para os endpoints de /authorize e /token durante o fluxo do authorization code
code_challenge
Um valor derivado do code_verifier que é enviado ao /authorize para ser verificado posteriormente
code_challenge_method
O método utilizado para derivar o code challenge, pode ser “plain” ou “S256”
Implementando o PKCE
O PKCE é uma extensão ao authorization code, então todas as etapas do fluxo do authorization code ainda serão necessárias, só é necessário enviar os parâmetros extras aqui descritos para que a extensão seja utilizada.
1 - Gerando o code_verifier
Para gerar o code_verifier uma string criptográficamente aleatória utilizando os caracteres não reservados, ou seja, caracteres que podem ser utilizados em uma URI.
O tamanho do code_verifier pode variar entre o mínimo de 43 caracteres e o máximo de 128 caracteres.
2 - Gerando o code_challenge
O code_challenge é derivado do code_verifier gerado na etapa anterior, e a forma de derivar este valor vai depender do code_challenge_method escolhido, sugerimos sempre utilizar o S256 quando possível, por ser o método mais seguro e que mitiga a maioria dos ataques.
plain
Para o code_challenge_method “plain”, o code_verifier e o code_challenge vão ser o mesmo valor, ou seja, nenhuma transformação é necessária.
S256
Para o “S256” é necessário utilizar as seguintes transformações no code_verifier.
BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
- Garantir que o encoding da string seja em ASCII
- Utilizar o algoritmo do SHA256 para transformar a string
- Utilizar o encoding do BASE64-URL Safe para transformar novamente a string
3 - Enviando os parâmetros no request de /authorize
Com os parâmetros criados e devidamente armazenados pela aplicação cliente, agora é necessário enviar o code_challenge e o code_challenge_method junto dos demais parâmetros do request do /authorize.
4 - Enviando o code_verifier no request de /token
Com o retorno do code do request de /authorize, agora a aplicação cliente irá enviar também o code_verifier junto dos demais parâmetros do /token.
Aviso
Uma alteração importante nesta etapa do /token é que não serão mais enviadas as credenciais da aplicação no header de Authorization. Agora, o client_id é enviado no body da request, em conjunto do code_verifier.
5 - Conclusão
Se tudo correr bem, será emitido o access token e o id token normalmente e sua aplicação já poderá autenticar os usuários.