使用 Cognito UnAuth 角色时的 IAM 权限问题
IAM permission issue when using Cognito UnAuth role
我正在制作一个简单的 React 应用程序以通过 DescribeDBInstances API 访问 RDS 数据。我想允许 public 访问,所以我使用启用了未验证访问的 Cognito。
我将以下策略附加到所提供的 UnAuth 角色,但在尝试使用来自 JavaScript (nodejs) 的 RDS API 时,我仍然遇到以下错误:
{
"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。
另外附上这个默认政策:
{
"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;
}
我在这里有点疯狂,似乎一切都设置正确。缺少什么?
我在 Cognito 的 IAM 角色文档中找到了答案:https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html(请参阅“访问策略”部分)
建议为 Cognito 增强身份验证并默认启用,但由于它在后台使用 GetCredentialForIdentity API,因此无论 IAM 策略如何,访问都仅限于某些 AWS 服务(RDS 不是允许的服务).我没有看到任何方法来覆盖此限制。
解决方案是切换到基本身份验证(您必须先在 Cognito 身份池设置中启用它)。这是我使用基本身份验证然后获取 RDS 实例的工作 nodejs 代码:
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
我正在制作一个简单的 React 应用程序以通过 DescribeDBInstances API 访问 RDS 数据。我想允许 public 访问,所以我使用启用了未验证访问的 Cognito。
我将以下策略附加到所提供的 UnAuth 角色,但在尝试使用来自 JavaScript (nodejs) 的 RDS API 时,我仍然遇到以下错误:
{
"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。
另外附上这个默认政策:
{
"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;
}
我在这里有点疯狂,似乎一切都设置正确。缺少什么?
我在 Cognito 的 IAM 角色文档中找到了答案:https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html(请参阅“访问策略”部分)
建议为 Cognito 增强身份验证并默认启用,但由于它在后台使用 GetCredentialForIdentity API,因此无论 IAM 策略如何,访问都仅限于某些 AWS 服务(RDS 不是允许的服务).我没有看到任何方法来覆盖此限制。
解决方案是切换到基本身份验证(您必须先在 Cognito 身份池设置中启用它)。这是我使用基本身份验证然后获取 RDS 实例的工作 nodejs 代码:
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