使用 .NET SDK 的 Cloudfront 签名 URL 不适用于带有空格的 S3 内容处置文件名

Cloudfront Signed URLs not working with S3 content disposition filenames with spaces using .NET SDK

我已经正确设置了带有 S3 源的 Cloudfront Signed URLs,并且正在使用 response-content-disposition 查询字符串参数来指定文件下载名称。当内容配置文件名不包含空格时,我使用 .NET AWS SDK AmazonCloudFrontUrlSigner.GetCannedSignedURL 方法 生成的签名 URLs 可以正常工作 。但是,如果文件名包含空格,我会被拒绝访问。因此,类似于下面的代码将生成一个 URL 拒绝访问。

var contentDisposition = HttpUtility.UrlEncode("attachment;filename=My File.txt");
var key = "example.txt?response-content-disposition="+contentDisposition;
return AmazonCloudFrontUrlSigner.GetCannedSignedURL(
    AmazonCloudFrontUrlSigner.Protocol.https,
    "myBucket",
    cloudFrontPrivateKey,
    key, cloudFrontAccessKeyId, expirationDateTime);

这显然与 URL 编码有关。

我已经通读了文档中关于 Serving Private Content through CloudFront. I read the code of the AmazonCloudFrontUrlSigner class 的所有信息。我还尝试了 UrlEncode 的多种组合,例如不编码、仅对文件名部分进行编码,甚至不编码但在生成签名 URL 后替换为编码版本。所有这些要么拒绝访问,要么给出签名与 url.

不匹配的错误

HttpUtility.UrlEncode 方法将 space 编码为 +,根据标准可以接受。但是,出于某种我不明白的原因,这会导致签名 URL 和内容处置出现问题。 space 作为 %20 的另一种编码工作正常。所以在编码之后,将 + 替换为 %20。工作版本是:

var contentDisposition = HttpUtility.UrlEncode("attachment;filename=My File.txt");
contentDisposition = contentDisposition.Replace("+", "%20");
var key = "example.txt?response-content-disposition="+contentDisposition;
return AmazonCloudFrontUrlSigner.GetCannedSignedURL(
    AmazonCloudFrontUrlSigner.Protocol.https,
    "myBucket",
    cloudFrontPrivateKey,
    key, cloudFrontAccessKeyId, expirationDateTime);