2017-04-06 3 views
0

Ich versuche herauszufinden, wie IDToken eines Benutzers aus AWS Cognito Identity authenticateUser-Aufruf überprüft werden kann.Verifizieren von AWS Cognito JWT IDToken mit einem JWK-Set mit njwt

Nach den hier gefundenen Schritten: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-identity-user-pools-using-id-and-access-tokens-in-web-api konnte ich zu dem Punkt kommen, wo ich die ID Token des Benutzers habe und ich habe die Kopfzeile und den Körper dekodiert.

Da ein IDToken das ist, was mein Kopf und Körper wie folgt aussehen:

Header:

{ 
    typ: 'JWT', 
    alg: 'RS256', 
    kid: '...' 
} 

Körper:

{ 
    sub: 'abcd...', 
    aud: 'abcdefg...', 
    email_verified: true, 
    token_use: 'id', 
    auth_time: 1491491773, 
    iss: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-...', 
    'cognito:username': 'username', 
    exp: 1491495373, 
    iat: 1491491773, 
    email: '[email protected]' 
} 

Dann wird der dritte Teil des IDToken ist die Signatur:

'T6tjQ...' // big long encoded string 

Der Teil, an dem ich festhalte, ist die Überprüfung der Signatur gegen meinen Signaturschlüssel. Ich kann nicht scheinen, dass dieser Teil funktioniert. Im Moment versuche ich, das njwt Knotenmodul hier zu finden: https://www.npmjs.com/package/njwt.

Da IDToken als 3 Teil . getrennt Base64-codierte Zeichenfolge und secretKey wie das folgende Javascript-Objekt:

{ 
    alg: 'RS256', 
    e: '...', 
    kid: '...', // matches kid of IDToken 
    kty: 'RSA', 
    n: 'abcdefg...', // Appears to be some big long encoded string 
    use: 'sig' 
} 

Dies ist, was ich mit dem njwt Knotenmodul versucht haben:

njwt.verify(IDToken, secretKey, 'RS256', function(err, verifiedJwt) 
{ 
    if (err) 
    { 
     console.log(err); 
    } 
    else 
    { 
     console.log('Verified'); 
    } 
}); 

Wenn ich es auf diese Weise versuche, bekomme ich:

TypeError: Not a buffer 
    at Verify.verify (crypto.js:426:24) 
    at .../node_modules/njwt/index.js:406:10 
    at Verifier.defaultKeyResolver (.../node_modules/njwt/index.js:72:10) 
    at Verifier.verify (.../node_modules/njwt/index.js:375:15) 
    at Object.jwtLib.verify (.../node_modules/njwt/index.js:457:21) 
    at repl:1:6 
    at REPLServer.self.eval (repl.js:110:21) 
    at repl.js:249:20 
    at REPLServer.self.eval (repl.js:122:7) 
    at Interface.<anonymous> (repl.js:239:12) 

Also dachte ich, vielleicht muss ich statt wie so von secretKey in secretKey.n passieren:

njwt.verify(IDToken, secretKey.n, 'RS256', function(err, verifiedJwt) 
{ 
    if (err) 
    { 
     console.log(err); 
    } 
    else 
    { 
     console.log('Verified'); 
    } 
}); 

Wenn ich es auf diese Weise versuchen, erhalte ich:

139980866705216:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:696:Expecting: CERTIFICATE 

Gefolgt von meinem console.log(err);:

{ [JwtParseError: Signature verification failed] 
    name: 'JwtParseError', 
    userMessage: 'Signature verification failed', 
    message: 'Signature verification failed', 
    jwtString: 'abcdefg...', 
    parsedHeader: { 
    typ: 'JWT', 
    alg: 'RS256', 
    kid: '...' 
    }, 
    parsedBody: { 
    sub: 'abcd...', 
    aud: 'abcdefg...', 
    email_verified: true, 
    token_use: 'id', 
    auth_time: 1491491773, 
    iss: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-...', 
    'cognito:username': 'username', 
    exp: 1491495373, 
    iat: 1491491773, 
    email: '[email protected]' 
    }, 
    innerError: undefined } 

Wie sollte ich in secretKey gehen? Was sollte secretKey sein und wie sollte es aussehen? Um ganz ehrlich zu sein bin ich mir nicht einmal sicher was njwt.verify erwartet.

Antwort

0

Es sieht wie das Problem aus, dass njwt.verify einen öffentlichen RSA-Schlüssel erwartete. Ich musste mein JWK Set-Objekt in einen öffentlichen RSA-Schlüssel konvertieren. Ich habe das mit dem Knotenmodul jwk-to-pem gemacht.

Bei gleichen secretKey von der Frage:

var jwkToPem = require('jwk-to-pem'); 

var pem = jwkToPem(secretKey); 

njwt.verify(IDToken, pem, 'RS256', function(err, verifiedJwt) 
{ 
    if (err) 
    { 
     console.log(err); 
    } 
    else 
    { 
     console.log('Verified'); 
    } 
}); 

Erfolg!