Amazon S3 无法通过 Cloudfront 上传文件
Posted
技术标签:
【中文标题】Amazon S3 无法通过 Cloudfront 上传文件【英文标题】:Amazon S3 can not upload file via Cloudfront 【发布时间】:2017-11-21 03:47:01 【问题描述】:我想通过 Cloudfront 将带有签名 URL 的文件上传到 S3。 Cloudfront 行为中允许 HTTP PUT。 存储桶策略
"Sid": "2", "Effect": "Allow", "Principal": "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1C2T5UJU07REZ" , "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject" ], "Resource": "arn:aws:s3:::testback/*"
CORS 配置中允许使用 HTTP PUT。 Cloudfront 用户也有读、写权限。 当我尝试上传带有签名 URL 的文件时。
curl -v -X PUT -F file=@hello.txt http://my-host.cloudfront.net/hello.txt?Expires=1514764800&Signature=MySig&Key-Pair-Id=My-KeyPair
我有一个错误:
InvalidRequest
你提供的授权机制不支持。请使用 AWS4-HMAC-SHA256。 5D5DEF3D06F4583C8rBCpTUzYwm1ccc8IfkNtUnkuLxr3RZ2n7xn1j+VvP5dpG+3NMpHKPiNQ5tKpJjVliZ9UBI52vk=
日志:
2017-06-19 03:23:08 FRA54 726 My-IP PUT 我的主机.cloudfront.net /hello.txt 400 - 卷曲/7.50.1 Expires=1514764800&Signature=My-Sig&Key-Pair-Id=My-KeyPair - 错误 MMHwKFzGuBzrlgP0yV71elcwEp2RVBAwJRJD1A5rO4Na6UmeKvcZPQ== 我的主机.cloudfront.net http 838 0.235 - -- 错误 HTTP/1.1
此外,GET、DELETE 也可以正常工作。
【问题讨论】:
【参考方案1】:来自 CloudFront 文档:
如果您使用的是源访问身份,并且您的存储桶位于需要签名版本 4 进行身份验证的区域之一,请注意以下几点:
支持
DELETE
、GET
、HEAD
、OPTIONS
和PATCH
请求,无需限定条件。如果您想向 CloudFront 提交
PUT
请求以将对象上传到您的 Amazon S3 存储桶,您必须在请求中添加x-amz-content-sha256
标头,并且标头值必须包含请求正文的 SHA256 哈希.http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#private-content-origin-access-identity-signature-version-4
您需要在 x-amz-content-sha256
请求标头中添加对象主体的 SHA256 的十六进制表示。
CloudFront 会使用在 PUT
中包含此标头作为内部切换到 V4 签名算法的神奇触发器,这似乎出乎意料...但由于上传是强制性的,因此 V4 签名不会是没有它就有效,所以它甚至可能不会尝试 V4(CloudFront 早于 Signature V4)。对于其他操作,V4 不需要修改用户代理行为,但对于 PUT
,CloudFront 在 V2 缺席时将其作为默认设置是有意义的,即使这是错误的,因此现有代码不会在它已经工作的地方中断。无论如何,这似乎应该是您的解决方案。
【讨论】:
@unknown 是否解决了您的问题? this AWS Forum Post 也是你的吗? 是的,这是有帮助的。 @Michael-sqlbot 如何为音频文件生成x-amz-content-sha256
?我使用aws-cloudfront-sign
在nodejs
中生成签名的url?
感谢您的出色回答...为了我的申请,只希望不需要添加该标题
@zavr 这是对 custom 原始标头的限制。如果您在缓存行为中将有问题的标头列入白名单,您仍然可以将其添加到触发器中的 cf.request.headers
对象中。以上是关于Amazon S3 无法通过 Cloudfront 上传文件的主要内容,如果未能解决你的问题,请参考以下文章
通过 S3 从 Amazon CloudFront 提供 gzip 后的 CSS 和 JavaScript
Gzip 与 Amazon S3/Cloudfront 失败
Amazon S3 + CloudFront 查询特定版本的存储文件