S3预签名URL添加response-content-disposition后遇SignatureDoesNotMatch错误
解决S3预签名URL添加response-content-disposition后签名不匹配的问题
问题原因
你手动在预签名URL后追加response-content-disposition参数导致签名不匹配,核心原因是:S3预签名URL的签名是基于生成请求时的所有参数、请求头信息计算的,事后新增的参数不在签名覆盖范围内,服务端验证时会判定实际请求参数与签名依据的参数不一致,因此返回SignatureDoesNotMatch错误。
正确配置方法
不要手动修改生成后的URL,而是在创建预签名请求时直接配置响应头覆盖规则,使用GetPreSignedUrlRequest的ResponseHeaderOverrides属性指定下载文件名——而非设置Headers.ContentDisposition(后者是修改对象本身的元数据,不是动态下载时的响应头)。
修改后的代码示例:
public static string GetPreSignedURL(string filename, string displayFilename) { GetPreSignedUrlRequest request = new(); request.BucketName = BucketName; request.Key = filename; request.Expires = DateTime.UtcNow.AddHours(24); // 通过响应头覆盖指定下载时的文件名 request.ResponseHeaderOverrides.ContentDisposition = $"attachment; filename={displayFilename}"; return client.GetPreSignedURL(request); }
额外优化(针对中文文件名)
如果需要支持中文文件名避免乱码,可按照RFC 5987标准对文件名进行URL编码,兼容绝大多数浏览器:
request.ResponseHeaderOverrides.ContentDisposition = $"attachment; filename*=UTF-8''{Uri.EscapeDataString(displayFilename)}";
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

