簡體   English   中英

使用 Cognito UnAuth 角色時的 IAM 權限問題

[英]IAM permission issue when using Cognito UnAuth role

我正在制作一個簡單的 React 應用程序來通過 DescribeDBInstances API 訪問 RDS 數據。 我想允許公共訪問,所以我使用 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM