Come posso decodificare e verificare la firma di un token Web JSON di Amazon Cognito?

5 minuti di lettura
0

Desidero utilizzare un pool di utenti Amazon Cognito come metodo di autenticazione per la mia applicazione. Desidero un modo sicuro per verificare l'ID e i token di accesso inviati dai clienti alla mia applicazione.

Breve descrizione

Quando i client utilizzano un pool di utenti per eseguire l'autenticazione all'applicazione, Cognito invia un token Web JSON (JWT) che è possibile decodificare, leggere e modificare. Per ottenere i dettagli dell'utente Cognito da un JWT, decodifica il token e verifica la firma.

Importante: prima di concedere l'accesso alle risorse, occorre verificare la firma.

Risoluzione

Verifica che Cognito abbia emesso JWT

Utilizza il seguente codice in JavaScript:

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!");
}

Nota: sostituisci user_pool_id con l'ID del pool di utenti e client_id con l'ID del client dell'app. Per il token ID, aggiorna il campo tokenUse su "id". Per un elenco dei parametri disponibili, consulta aws-jwt-verify sul sito Web di GitHub.

Se utilizzi un altro linguaggio di programmazione, consulta le librerie jwt.io sul sito Web di JWT o le librerie OpenID Connect sul sito Web di OpenID. Per un esempio di codice, consulta Decode and verify Amazon Cognito JWT tokens sul sito Web di GitHub.

Cognito restituisce tre token: il token ID, il token di accesso e il token di aggiornamento. Se utilizzi REST API, AWS Amplify o SDK AWS per autenticare un utente, ottieni tutti e tre i token.

Per l'interfaccia utente ospitata da Cognito, il token che si ottiene dipende dal tipo di concessione di autorizzazione utilizzato. Se utilizzi la concessione implicita, ottieni solo il token di accesso e ID. La concessione del codice di autorizzazione restituisce i token di accesso, ID e di aggiornamento. La concessione delle credenziali del client restituisce solo il token di accesso.

I token di accesso e ID includono un'intestazione, un payload e una firma. Il client non può decodificare o verificare il token di aggiornamento.

Di seguito è riportato un'intestazione del token ID di esempio. L'intestazione contiene l'ID chiave ("kid") e l'algoritmo ("alg") utilizzato per firmare il token. L'algoritmo RS256 è una firma RSA con SHA-256:

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

Di seguito è riportato un esempio di payload che contiene informazioni sull'utente e i timestamp della creazione e della scadenza del token:

{
  "sub": "aaaaaaaa-bbbb-cccc-dddd-example",
  "aud": "audience_example",
  "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"
}

La firma è una combinazione con hash e crittografata dell'intestazione e del payload.

Cognito genera due coppie di chiavi RSA per ogni pool di utenti. La chiave privata di ogni coppia viene utilizzata per firmare crittograficamente il token ID o il token di accesso. Le chiavi pubbliche si trovano all'indirizzo seguente:

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

Nota: sostituisci region con la Regione AWS in cui si trova il pool di utenti e userPoolId con l'ID del pool di utenti.

Il file JSON (jwks.json) è strutturato nel seguente 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"
    }]
}

Per verificare la firma di un JWT di Cognito, cerca la chiave pubblica con un ID chiave che corrisponda all'intestazione del token. Utilizza diverse librerie per verificare la firma del token ed estrarre i valori, come la scadenza e il nome utente.

Come best practice, verifica che il token non sia scaduto. Inoltre, assicurati che il pubblico ("aud") nel payload corrisponda all'ID del client dell'app creato nel pool di utenti di Amazon Cognito. La libreria aws-jwt-verify controlla automaticamente questi valori. Per ulteriori informazioni, consulta aws-jwt-verify sul sito Web di GitHub.

Memorizzazione nella cache di chiavi pubbliche

Poiché le chiavi pubbliche nell'endpoint JWKS vengono ruotate raramente, non è necessario scaricarle dall'endpoint ogni volta che si verifica un token. Invece, scarica le chiavi pubbliche e memorizzale nella cache sul computer locale dove si utilizza la logica di verifica dei token JWT.

Il "kid" è un identificatore univoco per le chiavi pubbliche. Per verificare un token JWT, controlla la cache locale per determinare se il "kid" nell'intestazione del token è presente nella cache. In assenza di memorizzazione nella cache, scarica le chiavi pubbliche dall'endpoint JWKS e aggiorna la cache.

Utilizzo di diversi metodi per verificare lo stato di scadenza o revoca di un token

Puoi revocare i token di aggiornamento e invalidare i token di accesso, ma non puoi revocare i token ID. Le librerie di verifica JWT verificano la scadenza del token, ma non controllano lo stato di revoca del token. Il controllo dello stato di revoca richiede un controllo lato server.

Informazioni correlate

Understanding user pool JSON web tokens (JWTs) (Comprendere i token web JSON del pool di utenti (JWT))

Come faccio a revocare i token JWT in Amazon Cognito utilizzando l'interfaccia della linea di comando di AWS?

AWS UFFICIALE
AWS UFFICIALEAggiornata 4 mesi fa