如何将带分组IAM角色的Cognito用户池用户转换为IAM凭证
不使用Identity Pool的Cognito分组角色凭证获取方案
核心实现逻辑
- 用户通过Cognito用户池完成登录后,获取返回的ID Token(不可使用Access Token)
- 从ID Token的Payload中提取
cognito:preferred_role字段,该字段值就是用户所属最高优先级分组绑定的IAM角色ARN;如果用户属于多组需要指定角色,可从cognito:roles数组中选择对应角色ARN - 调用AWS STS的
assumeRoleWithWebIdentity接口,传入ID Token、待认领的角色ARN、自定义会话标识,即可直接兑换得到AWS临时访问凭证(AccessKeyId、SecretAccessKey、SessionToken) - 兑换得到的临时凭证可直接注入AWS JavaScript SDK的配置项,即可按分组角色权限访问AWS服务
前置配置校验
你需要先确认以下配置正常,否则会出现权限报错:
- 分组绑定的IAM角色信任策略已配置正确,示例如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": "你的Cognito用户池应用客户端ID" }, "StringLike": { "cognito-identity.amazonaws.com:iss": "https://cognito-idp.你的区域.amazonaws.com/你的用户池ID" } } } ] }
- Cognito用户池的应用客户端配置中,已开启
cognito:roles、cognito:preferred_role属性到ID Token的映射 - Cognito分组已配置角色优先级,多组场景下优先级最高的分组对应角色会自动作为
cognito:preferred_role的值
JavaScript可运行代码示例
以下示例基于AWS JS SDK v3编写,可直接使用:
第一步:安装依赖
npm install @aws-sdk/client-sts
第二步:凭证兑换+SDK初始化代码
import { STSClient, AssumeRoleWithWebIdentityCommand } from "@aws-sdk/client-sts"; import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3"; // 示例用S3客户端,可替换为其他AWS服务客户端 // 替换为你自己的配置 const REGION = "你的AWS区域"; const COGNITO_ID_TOKEN = "用户登录后获取到的Cognito ID Token"; const ROLE_ARN = "从ID Token中提取的cognito:preferred_role值"; const ROLE_SESSION_NAME = "自定义会话名称,可用于CloudTrail审计,比如填用户ID"; // 初始化STS客户端 const stsClient = new STSClient({ region: REGION }); // 兑换临时凭证 async function getAwsCredentials() { const command = new AssumeRoleWithWebIdentityCommand({ RoleArn: ROLE_ARN, RoleSessionName: ROLE_SESSION_NAME, WebIdentityToken: COGNITO_ID_TOKEN, DurationSeconds: 3600 // 临时凭证有效期,单位秒,最大可设12小时,需和IAM角色的最大会话时长配置匹配 }); const response = await stsClient.send(command); return { accessKeyId: response.Credentials.AccessKeyId, secretAccessKey: response.Credentials.SecretAccessKey, sessionToken: response.Credentials.SessionToken, expiration: response.Credentials.Expiration }; } // 示例:使用拿到的凭证初始化S3客户端并调用接口 async function useAwsService() { const credentials = await getAwsCredentials(); // 初始化对应AWS服务客户端,直接注入凭证 const s3Client = new S3Client({ region: REGION, credentials: credentials }); // 调用服务接口,权限完全继承分组绑定的IAM角色 const buckets = await s3Client.send(new ListBucketsCommand({})); console.log("S3存储桶列表:", buckets.Buckets); } useAwsService();
注意事项
- 临时凭证过期前可重新调用
assumeRoleWithWebIdentity接口刷新,无需用户重新登录,只要ID Token仍在有效期内即可 - 该方案完全基于Cognito用户池分组的角色绑定逻辑,不会触发Identity Pool的权限覆盖,完全符合你的需求
- 所有访问请求的权限由分组绑定的IAM角色管控,满足内部人员直接访问AWS服务的场景
内容的提问来源于stack exchange,提问作者Warren Parad
相关产品推荐
相关产品推荐

