Segurança Nathan Geeksman

OAuth 2.1 e PKCE: fluxo de autorização moderno para SPAs e apps mobile

OAuth 2.1 e PKCE: fluxo de autorização moderno para SPAs e apps mobile

OAuth 2.1 e PKCE: fluxo de autorização moderno para SPAs e apps mobile

Introdução

OAuth 2.1 e PKCE são tecnologias modernas que desempenham um papel fundamental no contexto atual de desenvolvimento de software, especialmente quando se trata de proteger a segurança das aplicações web, SPAs (Single Page Applications) e apps móveis. Com a crescente necessidade de fornecer acesso seguro a recursos por meio de APIs (Interfaces de Programação de Aplicativos), os desenvolvedores enfrentam desafios em garantir a autenticação e autorização dos usuários enquanto minimizam as exposições de risco relacionadas à segurança.

A especificação OAuth 2.1 representa uma evolução significativa da versão anterior, introduzindo melhorias cruciais em termos de segurança e suporte a padrões estabelecidos pela indústria. Em paralelo, o mecanismo PKCE (Proof Key for Code Exchange) oferece uma forma robusta para proteger as trocas de códigos de autorização entre os clientes e o servidor do token.

Neste artigo, vamos explorar em detalhes como implementar OAuth 2.1 e PKCE em suas aplicações SPAs e apps móveis, focando nos benefícios e práticas recomendadas para garantir um fluxo de autorização seguro e transparente para seus usuários. Ao final desta leitura, você estará capacitado a integrar essas tecnologias em seu projeto atual, melhorando significativamente a segurança e escalabilidade da sua aplicação.

O que é e por que importa

OAuth 2.1 é uma especificação de autenticação e autorização para APIs, que substitui a versão anterior OAuth 2.0. Ela fornece um mecanismo de segurança robusto para permitir que as aplicações acessem recursos protegidos por meio de uma Autoridade de Autenticação (AA), sem expor credenciais de usuários.

A principal motivação pela adoção da OAuth 2.1 é a necessidade de melhorias significativas em termos de segurança, especialmente para lidar com os crescentes riscos associados às aplicações web e móveis. O Protocolo de Autorização OAuth 2.1 introduz um conjunto de mudanças importantes que visam melhorar a proteção contra ataques como o Phishing, reduzir a exposição de segurança relacionada à troca de códigos de autorização, e fornecer uma forma mais eficaz para os usuários autorizarem a acesso a recursos.

O mecanismo PKCE (Proof Key for Code Exchange) é um dos principais componentes da OAuth 2.1, que serve como uma extensão importante para lidar com as trocas de códigos de autorização entre o cliente e a Autoridade de Autenticação (AA). O PKCE oferece uma forma segura de verificar se a autorização veio realmente do proprietário da conta, evitando ataques como o CSRF (Cross-Site Request Forgery).

A implementação correta da OAuth 2.1 e do mecanismo PKCE é essencial para garantir que as aplicações web e móveis sejam seguras e escaláveis, protegendo os usuários de riscos relacionados à autenticação e autorização. Ao entender o conceito e a motivação por trás da OAuth 2.1, você pode tomar decisões informadas sobre como melhorar a segurança da sua aplicação.

Como funciona na prática

O fluxo de autorização OAuth 2.1 e PKCE é composto por várias etapas que garantem a segurança e autenticidade do processo. Aqui estão as principais etapas envolvidas:

  • Etapas do Fluxo de Autorização:
  • O cliente (SPA ou aplicação móvel) redireciona o usuário para a Autoridade de Autenticação (AA) com um código de autorização.
  • A AA redireciona o usuário para uma página de login, onde ele informa suas credenciais.
  • Após autenticação bem-sucedida, a AA gerencia um código de autorização e o envia de volta ao cliente através da URL de redirecionamento especificada no pedido de autorização.
  • Cálculo do Token:
  • O cliente envia o código de autorização para a AA, que então gera um token de acesso (token Bearer) para autenticar as requisições subsequentes ao recurso protegido.
  • Uso do Token:
  • O cliente utiliza o token Bearer em cada solicitação para acessar recursos protegidos pela Autoridade de Autenticação.

O PKCE, na prática, ajuda a garantir que as requisições de autorização sejam feitas corretamente e não sejam comprometidas por ataques como CSRF. Isso é alcançado através da geração de um código de prova (Proof Key for Code Exchange), que é compartilhado entre o cliente e a AA.

  • Processo PKCE:
  • O cliente gera um código de prova (S256) baseado no pedido de autorização.
  • A AA verifica o código de prova gerado pelo cliente antes de enviar o token Bearer.
  • Se o cliente tentar reutilizar um código de autorização, a AA não permitirá que ele seja usado para acessar recursos protegidos.

Essas etapas garantem que as aplicações web e móveis sejam seguras e escaláveis, protegendo os usuários de riscos relacionados à autenticação e autorização.

Exemplo real

Vamos considerar um exemplo de como funciona o OAuth 2.1 e PKCE num cenário real, utilizando uma aplicação web que precisa acessar os dados do usuário em um servidor externo.

// Exemplo de client.js para um SPA (Single-Page Application)
import axios from 'axios';

const clientId = 'CLIENT_ID';
const redirectUri = 'REDIRECIONAMENTO_URI';
const authorizationServerUrl = 'https://auth-server.com/authorize';
const tokenEndpoint = 'https://api-server.com/token';

// Geração do código de prova (PKCE) S256
function generatePkceCodeChallenge(authorizationRequest) {
  const codeVerifier = crypto.randomUUID();
  const codeChallenge = btoa(codeVerifier).replace(/\+/g, '-').replace(/\//g, '_');
  return [codeChallenge, codeVerifier];
}

async function authorize() {
  // Geração do código de prova (PKCE)
  const [codeChallenge, codeVerifier] = generatePkceCodeChallenge({
    client_id: clientId,
    redirect_uri: redirectUri,
    response_type: 'code',
    scope: 'perfil read',
  });

  // Construção da URL de redirecionamento
  const authorizationUrl = `${authorizationServerUrl}?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=code&scope=perfil%20read&code_challenge=${codeChallenge}&code_challenge_method=S256`;

  // Redirecionamento para a Autoridade de Autenticação (AA)
  window.location.href = authorizationUrl;
}

// Tratamento do código de autorização retornado pela AA
function handleAuthorizationCode(authorizationCode) {
  const tokenRequest = {
    grant_type: 'authorization_code',
    code: authorizationCode,
    redirect_uri: redirectUri,
    client_id: clientId,
    code_verifier: codeVerifier, // Código verificador do PKCE compartilhado anteriormente
  };

  axios.post(tokenEndpoint, tokenRequest)
    .then((response) => {
      const accessToken = response.data.access_token;
      console.log(`Token de acesso recebido: ${accessToken}`);
    })
    .catch((error) => {
      console.error('Erro ao gerar token:', error);
    });
}

// Observa a URL de redirecionamento para obter o código de autorização
window.addEventListener('hashchange', () => {
  const authorizationCode = window.location.hash.split('=')[1];
  handleAuthorizationCode(authorizationCode);
});

authorize();
const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();

// Definição da chave secreta para assinatura dos tokens
const privateKey = 'CHAVE_SECRETA_ACESSO';

app.post('/token', (req, res) => {
  // Verificação do código de prova (PKCE)
  const codeChallenge = req.body.code_challenge;
  const codeVerifier = req.body.code_verifier;

  // Geração do token Bearer com a assinatura digital
  const accessToken = jwt.sign({
    sub: 'USUÁRIO_ID',
    scope: 'perfil read',
  }, privateKey, {
    expiresIn: '1h',
    algorithm: 'HS256',
  });

  res.json({ access_token: accessToken });
});

app.listen(3000, () => {
  console.log('Servidor rodando na porta 3000');
});

Boas práticas

Armadilhas comuns

Boas práticas

  • Utilize a autenticação de tokens Bearer para proteger os recursos da API, em vez de realizar autenticação no nível do cliente.
  • Implemente o código verificador (code verifier) e o desafio do código (code challenge) para atender aos requisitos do PKCE.
  • Verifique a presença do código de autorização no URL de redirecionamento antes de gerar o token.
  • Utilize o grant_type correto (authorization_code) quando solicitando um token em troca de um código de autorização.
  • Mantenha as chaves de segurança (como a chave secreta para assinatura dos tokens) separadas e protegidas.

Armadilhas comuns

  • Não compartilhe o código verificador com ninguém, pois isso permitiria ao atacante gerar um token com autorização.
  • Não utilize códigos de autorização em diferentes solicitações. O cliente pode tentar reutilizar o código e obter múltiplos tokens de acesso sem aprovação do usuário.
  • No servidor, verifique se a solicitação para gerar o token inclui o grant_type correto (por exemplo, authorization_code) e a presença da chave secreta para assinatura dos tokens em suas configurações.

Conclusão

OAuth 2.1 e PKCE fornecem uma abordagem segura para fluxos de autorização modernos em SPAs e apps mobile, ao possibilitar a renovação de tokens de acesso sem que esses tokens estejam expostos nos clientes.

A chave para implementação dessas tecnologias é garantir que o código verificador e o desafio do código sejam gerados corretamente, assim como a presença do código de autorização no URL de redirecionamento. É também crucial manter as chaves de segurança separadas e protegidas.

Para avançar em conhecimento sobre OAuth 2.1 e PKCE, é recomendável explorar suas implementações práticas em diferentes linguagens de programação e frameworks de desenvolvimento, assim como examinar os recursos relacionados ao gerenciamento de tokens de acesso e segurança da informação para proteger seus fluxos de autorização.

Referências

  • OpenID Foundation. OAuth 2.1 Specification. Disponível em: https://openid.net/specs/oauth-v2_1.html. Acesso: 2024.
  • OWASP. OAuth and SAML Token Manipulation. Disponível em: https://owasp.org/www-project-token-manipulation/. Acesso: 2024.
  • IETF. RFC 6750 - The OAuth 2.0 Authorization Framework. Disponível em: https://datatracker.ietf.org/doc/html/rfc6750. Acesso: 2024.
  • Mozilla Developer Network (MDN). OAuth 2 and PKCE. Disponível em: https://developer.mozilla.org/en-US/docs/Learn/Security/OAuth_2_and_PKCE. Acesso: 2024.
  • OpenID Foundation. PKCE Profile for OAuth Resource Servers. Disponível em: https://openid.net/specs/draft-ietf-oauth-pkce-profile-01.html. Acesso: 2024.