You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过CloudFront转发带V4签名的PUT请求至S3时遇400/403错误

解决CloudFront转发S3 PUT请求的AWS V4签名不匹配问题

问题背景

直接用Postman向S3发送带AWS V4签名的PUT请求(示例如下)可以正常上传:

PUT https://example.com/to-process/test.json?X-Amz-Expires=86400&X-Amz-Date=20240415T033843Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATGD6OWCXBG3WY4FF%2F20240415%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=766f0a30fb6702597706d1cb8d88f9f8ea2de2334acf7ecdfce51b0bfdf07412

但通过配置了多源站转发的CloudFront(部分路径转EC2,部分转S3)发送请求时,先出现400错误,后转为403 SignatureDoesNotMatch错误。核心矛盾是:签名时用了CloudFront自定义域名作为Host,而CloudFront转发到S3时,S3用自身桶端点验证签名,导致签名不匹配。

解决方案

方案1:调整CloudFront源站请求策略,保证Host头一致性

  1. 创建自定义源站请求策略
    • 弃用默认的AllViewerExceptHostHeader,改为勾选「转发所有查看器请求头」,或明确指定包含Host头
    • 确保策略保留所有X-Amz-*开头的签名查询参数
  2. 关联策略到S3行为规则
    将自定义策略绑定到CloudFront中指向S3的路径行为上
  3. 统一签名时的Host头
    生成AWS V4签名时,使用S3桶的原生端点作为Host头(例如your-bucket.s3.eu-west-1.amazonaws.com),请求URL仍使用CloudFront自定义域名

方案2:使用CloudFront Origin Access Control(OAC)简化鉴权

由于S3桶开启了Block all public access,更安全的方式是让CloudFront直接和S3鉴权,避免查看端直接对S3签名:

  1. 在CloudFront控制台创建OAC,关联目标S3源站
  2. 给OAC配置S3桶的权限(例如s3:PutObject、s3:GetObject等)
  3. 将OAC绑定到CloudFront的S3行为规则上
  4. 查看端直接向CloudFront发送请求,无需附加S3签名,由CloudFront负责和S3的身份验证,彻底规避签名不匹配问题

方案3:配置S3支持自定义域名签名

如果必须让查看端基于CloudFront域名生成签名:

  1. 给S3桶配置自定义域名(即你的CloudFront域名example.com),可通过桶别名或静态网站托管实现
  2. 生成签名时,使用CloudFront自定义域名作为Host头
  3. 确保CloudFront转发请求时保留该Host头,S3会基于自定义域名验证签名,与你生成的签名匹配

验证步骤

  • 查看CloudFront访问日志,确认转发到S3的请求中Host头与签名时使用的一致
  • 用curl -v发送测试请求,检查请求头中的Host字段是否正确传递
  • 核对签名生成时的关键参数(X-Amz-Date、区域、服务、签名头列表)是否与实际请求完全一致

内容的提问来源于stack exchange,提问作者DaveB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:22:42