如何限制Amazon S3网站仅允许AWS Cognito认证用户通过托管UI访问
解决S3静态网站仅允许Cognito认证用户访问的方案
核心思路
彻底阻断S3的直接访问入口,用CloudFront作为唯一访问渠道,在CloudFront层强制校验Cognito用户的认证状态,同时让S3仅对CloudFront开放权限。
具体操作步骤
1. 锁定S3存储桶,禁止公开访问
- 打开S3控制台,选中目标存储桶,进入权限标签页
- 开启阻止所有公开访问的全部选项,确保桶内容无法直接公开访问
- 删除原有公开访问的桶策略,替换为仅允许CloudFront访问的策略(替换
YOUR_ACCOUNT_ID、YOUR_CLOUDFRONT_DIST_ID和YOUR_BUCKET_NAME为实际值):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::YOUR_ACCOUNT_ID:distribution/YOUR_CLOUDFRONT_DIST_ID" } } } ] }
2. 创建CloudFront分配,关联S3桶
- 进入CloudFront控制台,创建新分配:
- 源域名选择S3静态网站的端点(格式如
your-bucket.s3-website-us-east-1.amazonaws.com,而非默认的S3 REST端点) - 启用Origin Access Control (OAC),创建新的OAC并关联到该源,确保CloudFront能合法访问S3
- 默认缓存行为配置:
- 查看器协议策略设为HTTPS only
- 允许的HTTP方法选GET, HEAD, OPTIONS
- 启用Restrict viewer access,选择Use Signed URLs or Signed Cookies
- 信任的签名者选择Self,关联你的AWS账户
- 分配设置中,默认根对象设为网站首页(如
index.html)
- 源域名选择S3静态网站的端点(格式如
- 等待CloudFront部署完成(约10-15分钟)
3. 配置CloudFront与Cognito集成,强制前置认证
- 在CloudFront分配的行为标签页,编辑默认缓存行为:
- 找到Authentication模块,选择Amazon Cognito作为身份提供者
- 填入以下信息:
- 用户池ID:你的Cognito用户池ID
- 应用客户端ID:Cognito用户池中对应托管UI的应用客户端ID
- 登录URL:Cognito托管UI的登录地址(格式如
https://your-cognito-domain.auth.us-east-1.amazoncognito.com/login) - 注销URL:CloudFront分配的域名(如
https://your-cloudfront-id.cloudfront.net) - 受众:填写你的应用客户端ID
- 勾选Forward Authorization Context(可选,用于传递用户认证信息到后端)
- 保存配置,等待CloudFront更新部署
4. 调整Cognito应用客户端设置
- 进入Cognito用户池控制台,找到对应的应用客户端:
- 编辑回调URL,添加CloudFront分配的域名(如
https://your-cloudfront-id.cloudfront.net) - 编辑注销URL,同样添加CloudFront域名
- 确保允许的OAuth流包含Authorization code grant
- 勾选必要的OAuth范围(如
openid、email)
- 编辑回调URL,添加CloudFront分配的域名(如
5. 效果验证
- 直接访问S3静态网站URL:会返回
Access Denied,因为S3仅对CloudFront开放 - 访问CloudFront分配的域名:自动跳转到Cognito托管UI,完成Google登录或账号密码认证后,方可访问网站内容
对之前尝试方案的说明
- 仅限制Cognito域名访问S3:用户实际访问S3的请求来自浏览器,而非Cognito域名,因此该策略无法生效
- Cognito身份池+IAM角色:这种方案适合通过SDK获取临时凭证的客户端访问,静态网站直接访问时浏览器不会自动携带临时凭证,无法限制未认证访问
内容的提问来源于stack exchange,提问作者SwedishEmyrs
相关产品推荐
相关产品推荐

