使用 Cognito UnAuth 角色时的 IAM 权限问题 [英] IAM permission issue when using Cognito UnAuth role

查看:23
本文介绍了使用 Cognito UnAuth 角色时的 IAM 权限问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个简单的 React 应用程序,以通过 DescribeDBInstances API 访问 RDS 数据.我想允许公共访问,因此我使用启用了未经身份验证的访问的 Cognito.

I'm making a simple React app to access RDS data via DescribeDBInstances API. I want to allow public access, so I'm using Cognito with Unauthenticated access enabled.

我将以下策略附加到提供的 UnAuth 角色,但在尝试从 JavaScript (nodejs) 使用 RDS API 时,我仍然收到以下错误:

I have the following policy attached to the provided UnAuth role, yet I'm still getting the following error when trying to use the RDS API from JavaScript (nodejs):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "rds:DescribeDBInstances",
            "Resource": "*"
        }
    ]
}

AccessDenied: User: arn:aws:sts::(account):assumed-role/Cognito_TestUnauth_Role/CognitoIdentityCredentials is not authorized to perform: rds:DescribeDBInstances on resource: arn:aws:rds:us-east-1:(account):db:*

我编辑了我的帐户 ID.

I redacted my account ID.

还附加了此默认策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": "*"
        }
    ]
}

这是我的调用代码:

import { RDSClient, DescribeDBInstancesCommand } from "@aws-sdk/client-rds";
import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity";
import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity";

// see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-rds/index.html
export default async function getDbInstances() {
    const region = "us-east-1";
    const client = new RDSClient({
        region,
        credentials: fromCognitoIdentityPool({
          client: new CognitoIdentityClient({ region }),
          identityPoolId: "(my identity pool ID)",
        })
    });

    const command = new DescribeDBInstancesCommand({});
    return await client.send(command).DBInstances;
}

我在这里有点疯狂,似乎一切都设置正确.缺少什么?

I'm going a bit crazy here, it seems everything is set up correctly. What is missing?

推荐答案

我在 Cognito 的 IAM 角色文档中找到了答案:https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html(请参阅访问策略"部分)

I found the answer inside the IAM Roles documentation for Cognito: https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html (see "Access Policies" section)

建议为 Cognito 使用增强型身份验证并默认启用,但由于它在后台使用 GetCredentialForIdentity API,因此无论 IAM 策略如何,访问都仅限于某些 AWS 服务(RDS 不是允许的服务).我没有看到任何方法可以覆盖此限制.

Enhanced authentication is recommended for Cognito and enabled by default, but since it uses the GetCredentialForIdentity API under the hood, access is limited to certain AWS services regardless of IAM policy (RDS isn't an allowed service). I didn't see any way to override this limitation.

解决方案是切换到基本身份验证(您必须先在 Cognito 身份池设置中启用它).这是我使用基本身份验证然后获取 RDS 实例的工作 nodejs 代码:

The solution is to switch to basic authentication (you have to enable it first in the Cognito identity pool settings). Here's my working nodejs code to use basic auth and then fetch the RDS instances:

import { RDSClient, DescribeDBInstancesCommand } from "@aws-sdk/client-rds";
import { 
    CognitoIdentityClient, 
    GetIdCommand ,
    GetOpenIdTokenCommand
} from "@aws-sdk/client-cognito-identity";
import { getDefaultRoleAssumerWithWebIdentity } from "@aws-sdk/client-sts";
import { fromWebToken } from "@aws-sdk/credential-provider-web-identity";

const region = "us-east-1";
const cognitoClient = new CognitoIdentityClient({ region })

// see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-rds/index.html
export default async function getDbInstances() {
    const { Token, IdentityId } = await getTokenUsingBasicFlow();
    const client = new RDSClient({
        region,
        credentials: fromWebToken({ 
            roleArn: "arn:aws:iam::(account id):role/Cognito_RDSDataAppPoolUnauth_Role",
            webIdentityToken: Token,
            roleSessionName: IdentityId.substring(IdentityId.indexOf(":") + 1),
            roleAssumerWithWebIdentity: getDefaultRoleAssumerWithWebIdentity()
         })
    });

    const command = new DescribeDBInstancesCommand({});
    return (await client.send(command)).DBInstances;
}

async function getTokenUsingBasicFlow() {
    const getIdCommand = new GetIdCommand({ IdentityPoolId: "us-east-1:(identity pool id)" });
    const id = (await cognitoClient.send(getIdCommand)).IdentityId;
    const getOpenIdTokenCommand = new GetOpenIdTokenCommand({ IdentityId: id });
    return await cognitoClient.send(getOpenIdTokenCommand);
}

这是我编写实现时遵循的基本身份验证流程与增强的文档:https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html

Here's the documentation for the basic authentication flow vs enhanced that I followed to write my implementation: https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html

这篇关于使用 Cognito UnAuth 角色时的 IAM 权限问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆