2017-04-06 115 views
0

我試圖弄清楚如何驗證從AWS Cognito Identity authenticateUser調用中獲取的用戶IDToken。驗證AWS Cognito針對JWK設置的JWT IDToken使用njwt

按照以下步驟找到: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我已經能夠達到擁有用戶ID令牌的地步,並且我已經解碼了標頭和正文。

給定一個IDToken這就是我的頭和身體的樣子:

頭:

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

體:

{ 
    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]' 
} 

然後IDToken的第三部分是簽名:

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

我卡在的部分實際上是對照我的簽名密鑰驗證簽名。我似乎無法讓這部分工作。現在我試圖使用njwt節點模塊:https://www.npmjs.com/package/njwt

鑑於IDToken爲3部分.分離base64編碼字符串,如secretKey以下Javascript對象:

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

這就是我與njwt節點模塊嘗試:

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

當我嘗試這種方式時,我得到:

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) 

所以我想也許我需要secretKey.n而不是secretKey通過像這樣:

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

當我嘗試這樣我得到:

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

其次是我的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 } 

我該如何通過secretKeysecretKey應該是什麼,它應該是什麼樣子?說實話,我甚至不知道njwt.verify是什麼意思。

回答

0

看起來問題是njwt.verify期待公共RSA密鑰。我必須將我的JWK Set對象轉換爲公共RSA密鑰。我通過使用jwk-to-pem節點模塊來做到這一點。

鑑於同secretKey從這樣一個問題:

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'); 
    } 
}); 

成功!