如何实现单个Amazon Cognito用户访问指定S3存储桶?
问题解答
方案方向对吗?
方向是对的——用Cognito身份池关联IAM角色,通过用户的sub字段做条件限制S3访问,这本来就是实现认证用户隔离访问S3的标准方案之一。
策略报错的常见原因
你遇到的“此策略定义的部分操作、资源或条件未提供权限”报错,大概率是这几个问题:
- 资源ARN格式错了:S3的资源ARN要分清楚桶级和对象级,比如访问桶内对象得写
arn:aws:s3:::你的桶名/*,如果只写桶本身(arn:aws:s3:::你的桶名),那只能做桶级操作(比如ListBucket),和对象操作(比如PutObject)不匹配就会报错。 - 条件键用错了:Cognito身份池传递的用户sub属性,对应的IAM条件键是
cognito-identity.amazonaws.com:sub,不是直接写sub,用错键的话条件不生效,IAM会判定权限无效。 - 操作和资源不匹配:比如给了
s3:PutObject权限,但资源只指定了桶,没加/*,或者反过来给了ListBucket权限但资源写了对象路径,这种操作和资源范围不对应的情况也会触发报错。 - JSON语法错误:比如少了逗号、括号不配对,IAM直接不认这个策略,也会报类似错误。
正确的实现步骤
1. 先确认IAM角色的信任策略没问题
确保Cognito身份池能给认证用户分配这个角色,信任策略得包含身份池的ARN:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": "你的身份池ID" }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" } } } ] }
2. 配置正确的权限策略
如果要让用户只能访问桶下以自己sub命名的目录(比如你的桶名/${cognito-identity.amazonaws.com:sub}/),权限策略这么写:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::你的桶名/${cognito-identity.amazonaws.com:sub}/*" }, { "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::你的桶名", "Condition": { "StringLike": { "s3:prefix": "${cognito-identity.amazonaws.com:sub}/*" } } } ] }
要是想让用户访问整个桶(不限制子目录,只限定这个桶),就把第一个Statement的Resource改成arn:aws:s3:::你的桶名/*,ListBucket的条件可以去掉(或者保留如果只允许列自己的目录)。
3. 验证策略
在IAM控制台用“策略验证”功能,模拟Cognito认证用户的身份,输入对应的sub值,测试权限是否正常,提前排查语法或逻辑问题。
内容的提问来源于stack exchange,提问作者Andrej
相关产品推荐
相关产品推荐

