1
votes

Cognito - Vérifier la validité de idToken

J'ai une API principale dans Node.js qui récupère un jeton d'ID Amazon Cognito à partir d'un paramètre de requête. J'aurais besoin de vérifier si ce jeton est valide. Existe-t-il un moyen de vérifier cela en utilisant le SDK aws-sdk ou amazon-cognito-identity-js ?


1 commentaires

Il semble que vous ne puissiez jusqu'à présent valider les access_token qu'en temps réel à l'aide du point de terminaison / oauth2 / userInfo , qui n'accepte pas les id_tokens. hrrrr


5 Réponses :


0
votes

Le jeton d'identification de Cognito contient une réclamation «exp» lors du décodage, qui indique le temps après lequel un jeton d'identification ne serait pas valide. Citant la documentation ,

Heure d'expiration à partir de laquelle le jeton d'identification NE DOIT PAS être accepté pour traitement. Le traitement de ce paramètre nécessite que le la date / heure actuelle DOIT être antérieure à la date / heure d'expiration indiquée dans la valeur.

Pour décoder le jeton JWT en JavaScript, vous pouvez vous référer à une bibliothèque comme JsonWebToken , fourni par Auth0.

Pour utiliser la bibliothèque pour décoder un jeton d'identification existant à l'aide de la bibliothèque mentionnée, vous pouvez vous référer à l'extrait de code suivant:

// get the decoded payload ignoring signature, no secretOrPrivateKey needed
var decoded = jwt.decode(token);

// get the decoded payload and header
var decoded = jwt.decode(token, {complete: true});
console.log(decoded.header);
console.log(decoded.payload) 

Veuillez noter que le Les jetons JWT générés par Cognito sont compatibles OIDC, et vous pouvez également vous référer à ceci documentation pour plus d'informations sur les jetons de Cognito.


1 commentaires

Vous ne voulez pas ignorer la signature lors de la vérification des jetons, sinon il est trivial pour les attaquants de créer de faux jetons



0
votes

Amazon dispose d'une bibliothèque pour décoder et vérifier les jetons Cognito: https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt


0 commentaires

1
votes

Je fais l'enregistrement dans un lambda avec nœud à l'aide de la bibliothèque AWS https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt .

Par défaut, il vérifie AccessToken mais vous pouvez modifier pour valider IdToken.

remplacer:

console.log(`claim confirmed for ${claim["cognito:username"]}`);
result = {userName: claim["cognito:username"], clientId: claim.aud, isValid: true};

par

console.log(`claim confirmed for ${claim.username}`);
result = {userName: claim.username, clientId: claim.client_id, isValid: true};

et

if (claim.token_use !== "id") {
  throw new Error("claim use is not id");
}

by

if (claim.token_use !== 'access') {
  throw new Error('claim use is not access');
}

Vous pouvez même ajouter plus d'attributs personnalisés dans le résultat.


0 commentaires

1
votes

J'ai eu du mal avec cela pendant quelques jours et je viens de trouver comment faire cela, voici une fonction entièrement fonctionnelle qui effectue la validation pour vous tout ce que vous devez fournir est le userPoolId et le pool_region liés au pool de cognito que vous avez précédemment créé puis vous pouvez appeler cette fonction où vous voulez en envoyant le jeton en tant que paramètre et vous obtiendrez votre résultat sur la console si le jeton est valide ou non, voici comment l'implémenter:

  • créez un fichier appelé tokenValidation.js (par exemple)
  • collez-y ce code:
  • // Cognito data
       
    const userPoolId = "###########"; // Cognito user pool id here    
    const pool_region = '#########'; // Region where your cognito user pool is created
    
    const jwt = require('jsonwebtoken');
    const jwkToPem = require('jwk-to-pem');
    const request = require('request');
    
    
    // Token verification function
    const  ValidateToken = (token) => {
        console.log('Validating the token...')
        request({
            url: `https://cognito-idp.${pool_region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`,
            json: true
        }, (error, response, body) => {
            console.log('validation token..')
            if (!error && response.statusCode === 200) {
                pems = {};
                var keys = body['keys'];
                for(var i = 0; i < keys.length; i++) {
                    //Convert each key to PEM
                    var key_id = keys[i].kid;
                    var modulus = keys[i].n;
                    var exponent = keys[i].e;
                    var key_type = keys[i].kty;
                    var jwk = { kty: key_type, n: modulus, e: exponent};
                    var pem = jwkToPem(jwk);
                    pems[key_id] = pem;
                }
                //validate the token
                var decodedJwt = jwt.decode(token, {complete: true});
                if (!decodedJwt) {
                    console.log("Not a valid JWT token");
                    return;
                }
    
                var kid = decodedJwt.header.kid;
                var pem = pems[kid];
                if (!pem) {
                    console.log('Invalid token');
                    return;
                }
    
                jwt.verify(token, pem, function(err, payload) {
                    if(err) {
                        console.log("Invalid Token.");
                    } else {
                        console.log("Valid Token.");
                        console.log(payload);
                    }
                });
            } else {
                console.log(error)
                console.log("Error! Unable to download JWKs");
            }
        });
    }
    
    // Exporting it to call it anywere you want
    exports.ValidateToken = ValidateToken
    1. importez-le chaque fois que vous en avez besoin comme ceci: const validateToken = require ('./ tokenValidation')

    2. et enfin appelez-le comme ceci: validateToken.ValidateToken(result.getAccessToken().getJwtToken())

    Je sais que c'est une vieille question, mais j'espère vraiment que cela aidera les autres à l'avenir.


    1 commentaires

    cela vérifie uniquement s'il est de format valide et signé correctement, et s'il n'a pas expiré. mais il ne vérifie pas si l'utilisateur a vu ses privilèges révoqués depuis l'émission de ce jeton.



    0
    votes

    Vous pouvez simplement vérifier avec aws-sdk CognitoIdentityServiceProvider

    var params = {   AccessToken: 'STRING_VALUE' /* required */ };
     cognitoidentityserviceprovider.getUser(params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log(data);           // successful response });
    });
    


    0 commentaires