AWS cognito 返回 - '无效的登录令牌。不是 Cognito 代币'

问题描述 投票:0回答:3

我能够成功检索自定义身份验证提供商(开发人员身份验证)的身份令牌。这是使用 Cognito devauth 演示 servlet 实现的。

此令牌将返回到运行 AWS JS SDK 的浏览器。当我调用 getCredentialsForIdentiy 时,我收到“无效登录令牌”错误。

POST https://cognito-identity.us-west-2.amazonaws.com/ 400 (Bad Request)
app.js:150 Error: Invalid login token. Not a Cognito token.
    at constructor.a (aws-sdk-2.58.0.min.js:41)
    at constructor.callListeners (aws-sdk-2.58.0.min.js:41)
    at constructor.emit (aws-sdk-2.58.0.min.js:41)
    at constructor.emitEvent (aws-sdk-2.58.0.min.js:41)
    at constructor.e (aws-sdk-2.58.0.min.js:41)
    at i.runTo (aws-sdk-2.58.0.min.js:43)
    at aws-sdk-2.58.0.min.js:43
    at constructor.<anonymous> (aws-sdk-2.58.0.min.js:41)
    at constructor.<anonymous> (aws-sdk-2.58.0.min.js:41)
    at constructor.callListeners (aws-sdk-2.58.0.min.js:41) "NotAuthorizedException: Invalid login token. Not a Cognito token.
    at constructor.a (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:615)
    at constructor.callListeners (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:30513)
    at constructor.emit (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:30224)
    at constructor.emitEvent (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:16590)
    at constructor.e (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:12285)
    at i.runTo (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:43:7277)
    at https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:43:7482
    at constructor.<anonymous> (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:12495)
    at constructor.<anonymous> (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:16645)
    at constructor.callListeners (https://sdk.amazonaws.com/js/aws-sdk-2.58.0.min.js:41:30619)"

我将以下参数传递给 getCredentialsForIdentity。

identityId: <returned from servlet in region:guid format>
customRoleArn: <that maps to authenticated role>
Logins: <cognito-identity.amazonaws.com = token returned by congito>

我注意到新的 congnito 身份是使用 id browser 创建的。因此,令牌与 servlet 的交互似乎是正确的。但令牌被拒绝了。

我在这里缺少什么?我该如何进一步排除故障?

编辑: 浏览器客户端:javascript sdk,版本2.58。 本质上是为 this demo 编写一个 JS 客户端。修改只是为了获取令牌作为登录调用本身的一部分。生成的令牌对应于仅具有IOT客户端访问权限的角色。 (我想知道该政策是否需要扩大)。最终,用户将根据内部 ID 存储而不是此演示进行验证。

编辑2: 我没有针对 Cognito 服务调用 getCredentialsForIdentity,而是针对 STS 调用 ShouldRoleWithWebIdentity,这有效。使用基本流程而不是增强流程此处。。真的不知道为什么增强流程不起作用,但现在将采用基本流程方法。

amazon-web-services authentication amazon-cognito
3个回答
4
投票

因此,此处的 AWS 文档要么不准确,要么记录了低效的场景。

使用 JavaScript Cognito API,我的开发者提供商返回的令牌无法与针对 Cognito API 的 GetCredentialsForIdentity 一起使用。 (这就是促使我问这个问题的原因)。

但是,我可以对 STS API 使用相同的令牌并调用 AssumeRoleWithWebIdentity ,它本质上返回与上面的 GetCredentialsForIdentity 相同的响应参数。这就是我采取的方法。

第一个链接中的基本身份验证流程文档似乎不准确。因为它列出了“获取凭据”和“承担角色”作为必需步骤,但实际上只需要一个。此外,从浏览器中,这是对 Amazon 服务的 API 调用。因此,如果有效的话,使用增强流程而不是基本流程似乎并不是一个优势。


2
投票

我也遇到了同样的问题,使用的是 Javascript SDK V3,并且挣扎了很长时间!目前接受的答案对我有用 - 使用基本的身份验证流程而不是增强的。

我希望用一些当前使用 SDK V3 的读者可能会觉得有用的信息来补充上述内容:

在服务器上,使用 @aws-sdk/client-cognito-identity 中的 GetOpenIdTokenForDeveloperIdentityCommand 生成令牌并将其发送到客户端。

在客户端,我无法使用以下任何一项成功生成凭据:

  • 来自CognitoIdentity,来自@aws-sdk/credential-providers
  • GetCredentialsForIdentityCommand,来自@aws-sdk/client-cognito-identity
  • GetCredentialsForIdentityPoolCommand,来自@aws-sdk/client-cognito-identity

使用@aws-sdk/client-sts,以下确实有效:

    const { STSClient, AssumeRoleWithWebIdentityCommand } = require("@aws-sdk/client-sts")

    const client = new STSClient({region: cognitoRegion})
    const assumeRoleCommand = new AssumeRoleWithWebIdentityCommand({
        WebIdentityToken: openIdToken,  // the token your server sends to the client
        RoleArn: authRoleARN,  // the ARN of the role you set up on AWS Cognito / IAM
        RoleSessionName: userId // See note below
    })
    const credentialsResponse = await client.send(assumeRoleCommand)

    // the client apparently expects slightly different property names than the received credentials object
    const credentials = {
        accessKeyId: credentialsResponse.Credentials.AccessKeyId,
        expiration: credentialsResponse.Credentials.Expiration,
        secretAccessKey: credentialsResponse.Credentials.SecretAccessKey,
        sessionToken: credentialsResponse.Credentials.SessionToken
    }


    // Example using SES, you may be using different services
    const sesClient = new awsSes.SESClient({
        apiVersion: "2010-12-01", // yours may be different
        region: "us-east-1",      // yours may be different
        credentials: credentials
    })

注意:AssumeRoleWithWebIdentityCommand 文档讨论了 RoleSessionName 应该使用什么。


0
投票

我只能使用 Identity Pool APIs 获取临时凭证(无 STS)。我假设您拥有 Cognito 用户池中的 idToken:

import {
  CognitoIdentityClient,
  GetCredentialsForIdentityCommand,
  GetIdCommand,
  GetOpenIdTokenCommand,
} from '@aws-sdk/client-cognito-identity';

async function getAwsCredentialsFromIdentityPool(cognitoUserPoolIdToken: string) {
  const identityClient = new CognitoIdentityClient({region: 'us-west-1'});
  const getIdCommand = new GetIdCommand({
    // TODO: Enter your own account and identity pool ids
    AccountId: '012345678901',
    IdentityPoolId: 'us-west-1:e201dc59-9193-4577-94ee-d1133fbe31fa',
    Logins: {
      // TODO: Enter your own user pool id
      'cognito-idp.us-west-1.amazonaws.com/us-west-1_123456789': cognitoUserPoolIdToken,
    },
  });
  const getIdCommandOutput = await identityClient.send(getIdCommand);
  const getOpenIdTokenCommand = new GetOpenIdTokenCommand({
    IdentityId: getIdCommandOutput.IdentityId,
    Logins: {
      // TODO: Enter your own user pool id
      'cognito-idp.us-west-1.amazonaws.com/us-west-1_123456789': cognitoUserPoolIdToken,
    },
  });
  const getOpenIdTokenCommandOutput = await identityClient.send(getOpenIdTokenCommand);

  if (getOpenIdTokenCommandOutput.Token) {
    const getCredentialsForIdentityCommand = new GetCredentialsForIdentityCommand({
      IdentityId: getOpenIdTokenCommandOutput.IdentityId,
      Logins: {
        'cognito-identity.amazonaws.com': getOpenIdTokenCommandOutput.Token,
      },
    });
    const getCredentialsForIdentityCommandOutput = await identityClient.send(getCredentialsForIdentityCommand);
    return getCredentialsForIdentityCommandOutput.Credentials;
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.