Como posso decodificar e verificar a assinatura de um token Web JSON do Amazon Cognito?

4 minuto de leitura
0

Quero usar um grupo de usuários do Amazon Cognito como método de autenticação para meu aplicativo. Qual é uma forma segura de verificar a ID e os tokens de acesso enviados pelos clientes para meu aplicativo?

Breve descrição

Quando os clientes se autenticam em seu aplicativo com um grupo de usuários, o Amazon Cognito envia um token de ID. Você pode verificar o token de ID manualmente em cenários semelhantes aos seguintes:

  • Você criou um aplicativo Web e quer usar um grupo de usuários do Amazon Cognito para autenticação.
  • Você usa um grupo de usuários do Amazon Cognito para autenticação e um banco de identidades do Amazon Cognito para recuperar credenciais temporárias do AWS Security Token Service (AWS STS). O AWS Lambda é invocado com essas credenciais, mas o Lambda não tem informações sobre quem se autenticou originalmente com o grupo de usuários.

Para obter os detalhes do usuário do Amazon Cognito contidos em um token Web JSON (JWT) do Amazon Cognito, você pode decodificar o token e depois verificar a assinatura.

Resolução

A AWS liberou esta biblioteca, que você pode usar para verificar JWTs: https://github.com/awslabs/aws-jwt-verify

import { CognitoJwtVerifier } from "aws-jwt-verify";

// Verifier that expects valid access tokens:
const verifier = CognitoJwtVerifier.create({
  userPoolId: "<user_pool_id>",
  tokenUse: "access",
  clientId: "<client_id>",
});

try {
  const payload = await verifier.verify(
    "eyJraWQeyJhdF9oYXNoIjoidk..." // the JWT as string
  );
  console.log("Token is valid. Payload:", payload);
} catch {
  console.log("Token not valid!");
}

Depois que um usuário fizer login, um grupo de usuários do Amazon Cognito retorna um JWT. O JWT é uma string JSON codificada em base64url (“reivindicações”) que contém informações sobre o usuário. O Amazon Cognito retorna três tokens: o token de ID, o token de acesso e o token de atualização. O token de ID contém os campos do usuário definidos no grupo de usuários do Amazon Cognito.

Os tokens incluem três seções: um cabeçalho, uma carga e uma assinatura.

Veja a seguir o cabeçalho de um token de ID de exemplo. O cabeçalho contém a ID da chave (“kid”), além do algoritmo (“alg”) usado para assinar o token. Neste exemplo, o algoritmo é “RS256", que é uma assinatura RSA com SHA-256.

{
  "kid": "abcdefghijklmnopqrsexample=",
  "alg": "RS256"
}

Veja a seguir um exemplo da carga que contém informações sobre o usuário, bem como os timestamps de criação e expiração do token:

{
  "sub": "aaaaaaaa-bbbb-cccc-dddd-example",
  "aud": "xxxxxxxxxxxxexample",
  "email_verified": true,
  "token_use": "id",
  "auth_time": 1500009400,
  "iss": "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_example",
  "cognito:username": "anaya",
  "exp": 1500013000,
  "given_name": "Anaya",
  "iat": 1500009400,
  "email": "anaya@example.com"
}

A última seção é a assinatura, que é uma combinação criptografada e em hash do cabeçalho e da carga.

O Amazon Cognito gera dois pares de chaves RSA para cada grupo de usuários. A chave privada de cada par é usada para assinar o token de ID ou o token de acesso correspondente. As chaves públicas são disponibilizadas em um endereço no seguinte formato:

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json

O arquivo JSON (jwks.json) está estruturado no seguinte formato:

{
    "keys": [{
        "alg": "RS256",
        "e": "AQAB",
        "kid": "abcdefghijklmnopqrsexample=",
        "kty": "RSA",
        "n": "lsjhglskjhgslkjgh43lj5h34lkjh34lkjht3example",
        "use": "sig"
    }, {
        "alg":
        "RS256",
        "e": "AQAB",
        "kid": "fgjhlkhjlkhexample=",
        "kty": "RSA",
        "n": "sgjhlk6jp98ugp98up34hpexample",
        "use": "sig"
    }]
}

Para verificar a assinatura de um JWT do Amazon Cognito, primeiro procure a chave pública com uma ID da chave correspondente à ID da chave no cabeçalho do token. Em seguida, você pode usar bibliotecas, como aws-jwt-verify ou aquelas recomendadas por jwt.io ou OpenID Foundation, para validar a assinatura do token e extrair valores, como a validade e o nome de usuário.

Além da assinatura, também é uma prática recomendada verificar se:

  • O token não expirou.
  • O público (“aud”) especificado na carga corresponde à ID do cliente do aplicativo criada no grupo de usuários do Amazon Cognito.

A biblioteca aws-jwt-verify inclui essas verificações em seu nome. Para mais exemplos de código para decodificar e verificar um JWT do Amazon Cognito usando o Lambda, consulte Como decodificar e verificar tokens JWT do Amazon Cognito.


Informações relacionadas

Como verificar um token Web JSON

Como usar tokens com grupos de usuários

AWS OFICIAL
AWS OFICIALAtualizada há 2 anos