Проверка AWS Cognito JWT IDToken на набор JWK с помощью njwt

Я пытаюсь выяснить, как проверить идентификатор IDToken пользователя, полученный в результате вызова AWS Cognito Identity AuthenticateUser.

Следуя инструкциям, приведенным здесь: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-identity-user-pool-using-id-and-access-tokens-in-web-api I смог добраться до точки, где у меня есть токен идентификатора пользователя, и я декодировал заголовок и тело.

Учитывая 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 как строку в кодировке base64, разделенную на 3 части, . и 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 }

Как мне пройти secretKey? Что должно быть secretKey и как должно выглядеть? Честно говоря, я даже не уверен, чего ожидают njwt.verify.


person Jared Price    schedule 06.04.2017    source источник


Ответы (1)


Похоже, проблема заключалась в том, что 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');
    }
});

Успех!

person Jared Price    schedule 06.04.2017