IAM Policy变量${cognito-identity.amazonaws.com:sub}未识别及SQS权限配置问题
解决Cognito角色中${cognito-identity.amazonaws.com:sub}变量不被识别的问题
我之前在实现类似“每个用户专属SQS队列”的方案时,也踩过这个变量不生效的坑,咱们一步步来排查和解决:
1. 先确认IAM策略的资源配置是否正确
首先要确保你的IAM策略里,SQS队列的ARN正确使用了${cognito-identity.amazonaws.com:sub}变量,示例如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sqs:SendMessage", "sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes" ], "Resource": "arn:aws:sqs:us-east-1:123456789012:user-queue-${cognito-identity.amazonaws.com:sub}" } ] }
需要注意:
- 变量必须放在ARN的队列名称部分,不能随意插入其他位置
- 确保你实际创建队列时,确实遵循了
user-queue-+用户sub的命名规则
2. 检查角色的信任策略是否正确配置
这是最容易出错的环节!你的Cognito角色必须允许身份池的身份来假定它,并且要确保信任策略的条件能让Cognito正确传递sub变量。正确的信任策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": "us-east-1:xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" } } } ] }
重点细节:
cognito-identity.amazonaws.com:aud必须填写你的身份池ID,不能有误- 如果是给认证用户用的角色,
amr条件要包含authenticated(匿名用户对应unauthenticated) - 这个信任策略是Cognito传递用户
sub等身份信息的前提,没有它变量根本不会被解析
3. 验证Cognito身份池的关键设置
进入AWS控制台的Cognito身份池配置,检查两个核心选项:
- 将身份池ID作为受众(aud)传递:这个选项必须开启(默认是开启状态,但如果被手动关闭要重新打开),它是Cognito传递
sub等变量的基础 - 认证角色/未认证角色配置:如果用默认角色,要确保关联的就是你刚才配置了正确信任策略的角色;如果是基于规则选择角色,要确保规则逻辑正确,不会把用户导向错误的角色
4. 测试变量是否被正确解析
可以通过以下方式验证变量是否生效:
- 用客户端应用获取Cognito临时凭证,调用
sts:GetCallerIdentityAPI,查看返回的Arn里是否包含用户的真实sub值 - 尝试向用户专属队列发送一条消息,如果出现权限错误,查看CloudTrail日志中的
requestParameters,确认策略里的变量是否被替换成了实际的sub - 也可以用AWS CLI模拟测试,比如:
aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/user-queue-<用户真实sub值> --message-body "test" --profile cognito-user
如果发送成功,说明变量解析正常;如果报错AccessDenied,大概率是策略或信任配置存在问题
常见误区提醒
- 匿名用户的
sub是临时值,如果你是给认证用户提供服务,一定要确保用户是通过Cognito用户池完成认证的,而非匿名身份 - 队列名称不能包含AWS不允许的特殊字符,
sub是UUID格式,一般没问题,但要注意拼接后的队列名称长度不超过80字符 - IAM策略的变量是在获取临时凭证时解析的,不是实时替换,所以修改策略后需要重新获取凭证才会生效
内容的提问来源于stack exchange,提问作者li-raz
相关产品推荐
相关产品推荐

