Proof Key for Code Exchange (RFC 7636)

RFC 7636: Proof Key for Code Exchange (PKCE, pronuncia-se “pixy”) é uma especificação sobre uma contramedida contra a interceptação do código de autorização ataque.

authorization code interception attack

A especificação foi lançada em setembro de 2015. Ela adicionou:

  1. Parâmetro code_challenge e parâmetrocode_challenge_method para solicitações de autorização usando o fluxo de código de autorização, e
  2. Parâmetro code_verifier para solicitações de token que correspondem às solicitações de autorização.

Esse mecanismo permite que um servidor de autorização rejeite uma solicitação de token de um aplicativo malicioso que não possui um verificador de código.

2. Solicitação de autorização PKCE

2.1 Parâmetros de solicitação

Um pedido de autorização que usa PKCE sai com o parâmetro code_challenge e opcionalmente com o parâmetrocode_challenge_method.

2.2 Valor de desafio do código

O valor do parâmetro code_challenge é calculado aplicando um método de desafio (= lógica de computação) a um verificador de código.

2.3 Valor do verificador de código

Um verificador de código em si é uma string aleatória usando caracteres de [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~", com comprimento mínimo de 43 caracteres e máximo de 128 caracteres.

pkce authorization request

2.4 Método de desafio

Os métodos de desafio definidos são plain eS256. As respectivas lógicas de computação para converter um verificador de código em um desafio são as seguintes.

Método Logic
plain code_challenge = code_verifier
S256 code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

O método plain não muda a entrada, então o valor decode_verifier e o valor resultante de code_challenge são iguais.

O método S256 calcula o hash SHA-256 da entrada e, em seguida, codifica o valor do hash usando Base64-URL. Por exemplo, quando o valor de code_verifier é dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk, o valor decode_challenge torna-se E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM.

Quando o método de desafio usado é S256, um aplicativo cliente deve informá-lo incluindo o parâmetro code_challenge_method=S256 em uma solicitação de autorização. Quando o parâmetro code_challenge_method é omitido, um servidor de autorização assume plain como o valor padrão.

3. Resposta de autorização de PKCE

Depois de gerar um código de autorização, um servidor de autorização o salva em seu banco de dados com o desafio e o método de desafio contido na solicitação de autorização.

O servidor de autorização usará o desafio salvo e o método de desafio posteriormente para verificar uma solicitação de token do aplicativo cliente.

Uma resposta do endpoint de autorização não tem nada de especial para PKCE. É uma resposta normal, como de costume.

pkce authorization response

4. Solicitação de token PCKE

Depois de receber um código de autorização de um servidor de autorização, um aplicativo cliente faz uma solicitação de token. Além do código de autorização, a solicitação de token deve incluir o verificador de código usado para calcular o desafio do código.

O nome do parâmetro de solicitação para especificar um verificador de código é code_verifier.

pkce_token_request

5. Resposta de Token PKCE

5.1 Exigir verificador de código

O endpoint de token de um servidor de autorização que suporta PKCE verifica se uma solicitação de token contém um verificador de código válido.

Obviamente, essa verificação é realizada apenas quando grant_type é authorization_code e o código de autorização contido na solicitação de token está associado a um desafio.

Se uma solicitação de token não contiver um verificador de código válido, embora as condições acima atendam, a solicitação é considerada de um aplicativo malicioso e o servidor de autorização retorna uma resposta de erro.

5.2 Verificar o verificador de código

A verificação é realizada comparando dois desafios de código.

Um é o que estava contido na solicitação de autorização e está armazenado no banco de dados. A outra é o que um servidor de autorização calcula usando o verificador de código contido na solicitação token e o método de desafio armazenado no banco de dados.

Se os dois desafios de código forem iguais, a solicitação de token pode ser considerada como proveniente do aplicativo cliente legítimo que fez a solicitação de autorização original. Caso contrário, a solicitação de token deve ser considerada de um aplicativo malicioso.

5.3 Emitir token de acesso

Se uma solicitação de token for verificada, um servidor de autorização emitirá um token de acesso normalmente.

pkce_token_response

6. Experimente o PKCE

6.1 Preparação

6.1.1 Inscreva-se

Se você ainda não tem sua conta Authlete, inscreva-se gratuitamente. Não toma nem um minuto.

6.1.2 Servir chave API e ID de cliente

Uma chave de API de serviço e um client ID são necessários para fazer uma solicitação de autorização.

Se você não excluiu o primeiro servidor de autorização e o primeiro aplicativo cliente que foram criados automaticamente no registro da conta, você já tem uma chave de API de serviço e um ID de cliente.

A chave de API de serviço do primeiro servidor de autorização é escrita no e-mail que você recebeu após o registro da conta. Além disso, você pode encontrá-lo em Service Owner Console.

O ID do cliente do primeiro aplicativo cliente também é escrito no e-mail. Além disso, você pode encontrá-lo no Console do desenvolvedor.

6.1.3 Serviço e configuração do cliente

Se você alterou as configurações do servidor de autorização (= Serviço em Console do proprietário do serviço) e do aplicativo cliente (= App no Console do desenvolvedor) de os valores padrão, ajuste alguns itens de configuração conforme descrito nas tabelas abaixo.

Tabela. Configurações de serviço no console do proprietário do serviço

Tab Parâmetro Valor
Autorização Supported Grant Types Incluir AUTHORIZATION_CODE
Autorização Supported Response Types Incluir CODE
Autorização Authorization Endpoint / Direct Endpoint Enabled Selecione SIM
Autorização Token Endpoint / Direct Endpoint Enabled Selecione SIM

Tabela. Configurações do cliente no console de desenvolvedor do cliente

Tab Parâmetro Valor
Basic Client Type Selecione PUBLIC
Authorization Grant Types Incluir AUTHORIZATION_CODE
Authorization Response Types Incluir CODE
Authorization Redirect URIs https://api.authlete.com/api/mock/redirection/service-api-key

6.2. Pedido de Autorização

6.2.1. Endpoint de autorização de acesso

Acesse o URL abaixo com seu navegador da web. Não se esqueça de substituir service-api-key e client-id por sua chave de API de serviço e ID de cliente.

https://api.authlete.com/api/auth/authorization/direct/service-api-key
  ?client_id=client-id
  &response_type=code
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

Observe que a URL contém o parâmetro code_challenge e o parâmetro code_challenge_method. Eles são exatamente os parâmetros que você deseja experimentar.

6.2.2 Pedido de Autorização

No endpoint de autorização, uma página de autorização é exibida. Você pode encontrar um formulário de login na página. Insira a chave da API e o segredo da API do serviço no formulário de login e clique no botão Autorizar.

login form in authorization page

Quanto ao motivo de por que você pode usar as credenciais de API do serviço como se fossem um login e senha do usuário final, leia a Nota Técnica em “3.2. Credenciais de entrada “em” Introdução “.

6.2.3 Resposta de Autorização

Uma resposta de um endpoint de autorização é retornada para um endpoint de redirecionamento que um aplicativo cliente registrou com antecedência. Uma vez que a configuração dos URIs de redirecionamento do aplicativo cliente contém um URI de redirecionamento, https://api.authlete.com/api/mock/redirection/service-api-key, a resposta do endpoint de autorização é passada para o ponto de extremidade de redirecionamento e processado lá.

A implementação do endpoint de redirecionamento é fornecida apenas para ajudar os desenvolvedores. A implementação exibe os valores dos parâmetros que recebe. Por exemplo, se uma resposta de autorização contém um código de autorização, o endpoint de redirecionamento exibe seu valor conforme mostrado abaixo.

authorization_code

Além disso, quando apropriado, ele desserializa um token de ID serializado e mostra um formulário para enviar uma solicitação de token. Você usará o formulário na próxima seção.

6.3 Solicitação de token

6.3.1 Formulário de solicitação de token

Conforme mencionado na seção anterior, quando uma resposta de autorização contém um código de autorização, o endpoint de redirecionamento exibe um formulário para enviar uma solicitação de token com o código de autorização.

O formulário possui um campo de entrada para um verificador de código. Insira ali dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk, e o formulário finalmente terá a aparência abaixo.

token_request_form

Clique no botão Enviar para fazer uma solicitação de token com o verificador de código. Observe que um código de autorização expira em 10 minutos, portanto, não gaste mais tempo do que 10 minutos após a exibição da página de redirecionamento.

6.3.2. Resposta Token

Se o código de autorização e o verificador de código inserido no formulário forem válidos, um token de acesso será retornado na forma de JSON como a seguir.

{
    "access_token": "KPLXrl_wJSHqU708R9kp3bNRGi0LgKUdh0kh-CQhx9g",
    "refresh_token": "YLRJXfratV4yq0_65seCT0bF6YxxgU5jKBUvhOZPrb4",
    "scope": null,
    "token_type": "Bearer",
    "expires_in": 86400
}

Parabéns! Você conseguiu obter um token de acesso usando o fluxo de código de autorização protegido pelo PKCE.

6.4. Configuração PKCE

Authlete fornece um item de configuração para PKCE. Faça login Service Owner Console, selecione um serviço e clique na guia Autorização, e você poderá encontrar um item de configuração booleana denominado “Chave de prova para troca de código (RFC 7636) “

pkce_configuration

Se YES for selecionado, o parâmetro de solicitação code_challenge é sempre necessário para solicitações de autorização usando o fluxo de código de autorização. O valor padrão é NO.

Selecione YES para melhor segurança. Isso faz com que o servidor de autorização rejeite qualquer solicitação de autorização usando o fluxo de código de autorização que não é acompanhado pelo parâmetro de solicitação code_challenge.