通过Cognito用户池Web Token获取STS令牌遇AccessDenied错误求助
排查STS AssumeRoleWithWebIdentity AccessDenied错误的原因及解决方法
核心问题分析
你遇到的AccessDenied错误,大概率是因为凭证获取流程与IAM角色信任策略不匹配,或是流程本身不符合Cognito联合身份池的规范。以下是具体排查步骤和修复方案:
1. 检查IAM角色信任策略的配置逻辑
当前你的角色信任策略使用了cognito-identity.amazonaws.com:aud条件,但这个条件仅适用于通过Cognito身份池获取身份ID后调用STS的场景。如果你直接用Cognito用户池的ID Token调用AssumeRoleWithWebIdentity,STS会验证Token本身的aud声明(即用户池客户端ID),而非身份池ID,导致条件不匹配。
修复方案二选一:
方案A:直接用用户池Token调用STS
修改信任策略,将Principal指定为用户池的OIDC提供商,并验证Token的aud:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-idp.<你的区域>.amazonaws.com/<你的用户池ID>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-idp.<你的区域>.amazonaws.com/<你的用户池ID>:aud": "<你的用户池客户端ID>" } } } ] }方案B:通过Cognito身份池获取凭证(推荐)
如果你想保留当前信任策略,需改用身份池的标准流程——先用用户池Token获取身份ID,再由身份池自动处理STS调用:import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity"; import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity"; const authTokens = authService.getAuthTokens(); useEffect(() => { const getCredentials = async () => { const client = new CognitoIdentityClient({ region: "<你的区域>" }); const credsProvider = fromCognitoIdentityPool({ client, identityPoolId: "<你的身份池ID>", logins: { "cognito-idp.<你的区域>.amazonaws.com/<你的用户池ID>": authTokens.id_token } }); const creds = await credsProvider(); console.log("creds", creds); }; getCredentials(); }, [authTokens]);
2. 验证ID Token的有效性
用jwt.io解码你的ID Token,检查以下关键声明:
aud:必须与用户池客户端ID完全一致iss:必须是用户池的OIDC提供商URL(格式:https://cognito-idp.<区域>.amazonaws.com/<用户池ID>)exp:Token未过期
如果Token存在无效声明或已过期,STS会直接拒绝请求。
3. 检查Cognito身份池的配置
进入AWS控制台的Cognito身份池页面,确认:
- 认证提供者:已添加你的Cognito用户池(填写用户池ID和客户端ID)
- 角色映射:已将认证用户对应的角色设置为
my-assume-role-with-web-identity
内容的提问来源于stack exchange,提问作者kodi1911
相关产品推荐
相关产品推荐

