Cognito 无法提供启用 Evidently 命令的有效凭据

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

我有一个 CloudWatch Evidently 项目,我想用它来控制公共 Web UI 上的功能标志。由于我无法在客户端应用程序中嵌入持久的 AWS 凭证,因此我知道 Cognito 是推荐的工具,可以允许未经身份验证的方式访问 AWS 服务。

我已经使用此 CloudFormation 模板创建了 Cognito 身份池、IAM 角色以及两者之间的链接:

    CognitoIdentityPool:
      Type: AWS::Cognito::IdentityPool
      Properties:
        AllowClassicFlow: True
        AllowUnauthenticatedIdentities: True
        IdentityPoolName: my-identity-pool
    UIIAMRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement: 
            - Effect: Allow
              Principal: 
                Federated: cognito-identity.amazonaws.com
              Action: sts:AssumeRoleWithWebIdentity
              Condition:
                StringEquals:
                  cognito-identity.amazonaws.com:aud: !Ref CognitoIdentityPool
                ForAnyValue:StringLike:
                  cognito-identity.amazonaws.com:amr: unauthenticated
        MaxSessionDuration: 3600
        Policies: 
          - PolicyName: root
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Action:
                    - cognito-identity:GetCredentialsForIdentity
                    - evidently:ListFeatures
                    - evidently:EvaluateFeature
                  Resource: '*'
    IdentityPoolRoleAttachment:
      Type: AWS::Cognito::IdentityPoolRoleAttachment
      Properties:
        IdentityPoolId: !Ref CognitoIdentityPool
        Roles:
          unauthenticated: !GetAtt UIIAMRole.Arn 

控制台 UI 显示按预期创建的所有内容:在身份池上启用了来宾访问,与创建的 IAM 角色关联,并且该角色具有包含正确的明显权限的策略。

但是当我尝试接收凭据时,它说该角色无权使用 Evidently 功能:

$ aws cognito-identity get-id --identity-pool us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
    "IdentityId": "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

$ aws cognito-identity get-credentials-for-identity --identity-id us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

{
    "IdentityId": "us-east-1:xxxxxxxxxxxxxxxxxxxxx",
    "Credentials": {
        "AccessKeyId": "xxxxxxxxxxxxxxxxxxxxx",
        "SecretKey": "xxxxxxxxxxxxxxxxxxxxx",
        "SessionToken": "xxxxxxxxxxxxxxxxxxxxx",
        "Expiration": "2023-11-30T11:03:53-05:00"
    }
}

$ export AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxxx

$ export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxx

$ export AWS_SESSION_TOKEN=xxxxxxxxxxxxxxxxxxxxx

$ aws evidently list-features --project my-evidently-project

An error occurred (AccessDeniedException) when calling the ListFeatures operation: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/my-role-UIIAMRole-xxxxxxxxxx/CognitoIdentityCredentials is not authorized to perform: evidently:ListFeatures on resource: arn:aws:evidently:us-east-1:xxxxxxxxxxxx:project/my-evidently-project/feature/* 

我还尝试使用 Node SDK 获取和使用凭据:

const evidentlyClient = new EvidentlyClient({
    region: 'us-east-1',
    credentials: fromCognitoIdentityPool({
      identityPoolId: 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
      clientConfig: { region: 'us-east-1' }
    })
  })
  const featureResp = await evidentlyClient.send(
    new ListFeaturesCommand({
      project: 'arc-editorial-search-api'
    })
  )

也因同样的错误而失败。

谁能告诉我我做错了什么?

amazon-web-services amazon-cognito amazon-iam evidently
1个回答
0
投票

我认为问题中的方法是使用增强流程,根据本文档,该流程的权利有限。以下命令有效,我认为这对应于基本流程:

$ aws cognito-identity get-id --identity-pool us-east-1:xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx
{
    "IdentityId": "us-east-1:xxxxxxxxx"
}

$ aws cognito-identity get-open-id-token --identity-id us-east-1:xxxxxxxxx
{
    "IdentityId": "us-east-1:xxxxxxxxx",
    "Token": "xxx..."
}

$ aws sts assume-role-with-web-identity --role-arn arn:aws:iam::xxxxxxxxxxxx:role/my-iam-role --role-session-name test --web-identity-token xxx...
{
    "Credentials": {
        "AccessKeyId": "xxxxxxxxxxxxxxx",
        "SecretAccessKey": "xxxxxxxxxxxxxxx",
        "SessionToken": "xxxxxxxxxxxxxxx...",
        "Expiration": "2023-12-01T15:56:05+00:00"
    },
    "SubjectFromWebIdentityToken": "us-east-1:xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "AssumedRoleUser": {
        "AssumedRoleId": "xxxxxxxxxxxxxxxx:test",
        "Arn": "arn:aws:sts::xxxxxxxxxxxx:assumed-role/my-iam-role/test"
    },
    "Provider": "cognito-identity.amazonaws.com",
    "Audience": "us-east-1:xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

$ AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=xxx AWS_SESSION_TOKEN=xxx aws evidently list-features --project arc-editorial-search-api
{
    "features": [
        ...
    ]
}

并使用 SDK:

import {
  CognitoIdentityClient,
  GetIdCommand,
  GetOpenIdTokenCommand
} from '@aws-sdk/client-cognito-identity'
import {
  STSClient,
  AssumeRoleWithWebIdentityCommand
} from '@aws-sdk/client-sts'
import {
  EvidentlyClient,
  ListFeaturesCommand
} from '@aws-sdk/client-evidently'
;(async () => {
  const cognitoClient = new CognitoIdentityClient({ region: 'us-east-1' })
  const { IdentityId } = await cognitoClient.send(
    new GetIdCommand({
      AccountId: 'xxxxxxxxxxxx',
      IdentityPoolId: 'us-east-1:xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx'
    })
  )
  const { Token: WebIdentityToken } = await cognitoClient.send(
    new GetOpenIdTokenCommand({
      IdentityId
    })
  )

  const stsClient = new STSClient({ region: 'us-east-1' })
  const {
    Credentials: {
      AccessKeyId: accessKeyId = '',
      SecretAccessKey: secretAccessKey = '',
      SessionToken: sessionToken = ''
    } = {}
  } = await stsClient.send(
    new AssumeRoleWithWebIdentityCommand({
      RoleArn:
        'arn:aws:iam::xxxxxxxxxxxxx:role/my-iam-role',
      RoleSessionName: 'test',
      WebIdentityToken
    })
  )
  if (accessKeyId && secretAccessKey && sessionToken) {
    const evidentlyClient = new EvidentlyClient({
      region: 'us-east-1',
      credentials: {
        accessKeyId,
        secretAccessKey,
        sessionToken
      }
    })
    const featureResp = await evidentlyClient.send(
      new ListFeaturesCommand({
        project: 'arc-editorial-search-api'
      })
    )
    console.log(featureResp)
  }
})()
© www.soinside.com 2019 - 2024. All rights reserved.