当我设置包含“+"的响应标头覆盖时,为什么我的 S3 预签名请求无效? [英] Why is my S3 pre-signed request invalid when I set a response header override that contains a "+"?
问题描述
我正在使用 Amazon .NET SDK 生成这样的预签名 URL:
I'm using the Amazon .NET SDK to generate a pre-signed URL like this:
public System.Web.Mvc.ActionResult AsActionResult(string contentType, string contentDisposition)
{
ResponseHeaderOverrides headerOverrides = new ResponseHeaderOverrides();
headerOverrides.ContentType = contentType;
if (!string.IsNullOrWhiteSpace(contentDisposition))
{
headerOverrides.ContentDisposition = contentDisposition;
}
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
.WithBucketName(bucketName)
.WithKey(objectKey)
.WithProtocol(Protocol.HTTPS)
.WithExpires(DateTime.Now.AddMinutes(6))
.WithResponseHeaderOverrides(headerOverrides);
string url = S3Client.GetPreSignedURL(request);
return new RedirectResult(url, permanent: false);
}
这很完美,除非我的 contentType
包含一个 +
.例如,当我尝试获取内容类型为 image/svg+xml
的 SVG 文件时,就会发生这种情况.在这种情况下,S3 会抛出 SignatureDoesNotMatch
错误.
This works perfectly, except if my contentType
contains a +
in it. This happens when I try to get an SVG file, for example, which gets a content type of image/svg+xml
. In this case, S3 throws a SignatureDoesNotMatch
error.
错误消息显示 StringToSign
如下:
The error message shows the StringToSign
like this:
GET 1234567890 /blah/blabh/blah.svg?response-content-disposition=filename="blah.svg"&response-content-type=image/svg xml
注意 response-content-type 中有一个空格,现在显示的是 image/svg xml
而不是 image/svg+xml
.在我看来,这就是导致问题的原因,但解决问题的正确方法是什么?
Notice there's a space in the response-content-type, where it now says image/svg xml
instead of image/svg+xml
. It seems to me like that's what is causing the problem, but what's the right way to fix it?
我应该编码我的内容类型吗?将其括在引号内或其他内容中?文档对此没有任何说明.
Should I be encoding my content type? Enclose it within quotes or something? The documentation doesn't say anything about this.
推荐答案
更新
此错误已自 1.4.1.0 版起修复 的 SDK.
这是一个已确认的 AWS 开发工具包中的错误,因此,在他们发布修复程序之前,我将使用此 hack 使事情正常进行:
This is a confirmed bug in the AWS SDK, so until they issue a fix I'm going with this hack to make things work:
准确指定您希望它在响应标头中的外观的内容类型.因此,如果您希望 S3 返回 image/svg+xml
的内容类型,请完全像这样设置:
Specify the content type exactly how you want it to look like in the response header. So, if you want S3 to return a content type of image/svg+xml
, set it exactly like this:
ResponseHeaderOverrides headerOverrides = new ResponseHeaderOverrides();
headerOverrides.ContentType = "image/svg+xml";
现在,继续像往常一样生成预签名的请求:
Now, go ahead and generate the pre signed request as usual:
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
.WithBucketName(bucketName)
.WithKey(objectKey)
.WithProtocol(Protocol.HTTPS)
.WithExpires(DateTime.Now.AddMinutes(6))
.WithResponseHeaderOverrides(headerOverrides);
string url = S3Client.GetPreSignedURL(request);
最后,使用适合您的内容类型的正确 URL 编码值修复"结果 URL:
Finally, "fix" the resulting URL with the properly URL encoded value for your content type:
url = url.Replace(contentType, HttpUtility.UrlEncode(contentType));
是的,这是一个肮脏的解决方法,但是,嘿,它对我有用!:)
Yes, it's a dirty workaround but, hey, it works for me! :)
这篇关于当我设置包含“+"的响应标头覆盖时,为什么我的 S3 预签名请求无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!