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

S3预签名URL上传文件带x-amz-checksum-sha256报403求助

S3预签名URL PUT请求添加SHA256校验和触发403的解决方法

问题场景

我们在实现S3对象完整性校验时,分段上传通过CompleteMultipartUploadAsync传入ChecksumSHA256参数功能正常:

var completeRequest = new CompleteMultipartUploadRequest
{
    BucketName = bucketName,
    Key = key,
    UploadId = uploadId,
    ChecksumSHA256 = sha256ofFile
};
completeRequest.AddPartETags(parts.Select(p => new PartETag(p.PartNumber, p.ETag)).ToArray());
await amazonS3Client.CompleteMultipartUploadAsync(completeRequest);

但小文件使用预签名URL上传时,添加x-amz-checksum-sha256请求头会返回403 Forbidden:

public async Task SimplePutAsync(string presignedURL, ByteArrayContent content, string sha256ofFile)
{
    var httpClient = new HttpClient();
    content.Headers.Add("x-amz-checksum-sha256", sha256ofFile);
    var response = await httpClient.PutAsync(presignedURL, content);
    response.EnsureSuccessStatusCode();
}

同时在.NET SDK中遇到以下问题:

  • 找不到对应AWS CLI中generate_presigned_post的等效方法
  • GetPreSignedUrlRequest的Metadata属性为只读,无法在生成预签名URL时配置
  • GeneratePreSignedURL的additionalProperties参数缺乏官方文档说明

核心原因

预签名URL的签名范围包含请求头,若生成URL时未将x-amz-checksum-sha256纳入签名范围,后续请求携带该头会导致签名不匹配,触发403错误。

解决方案

1. 生成预签名URL时包含校验和请求头

使用GetPreSignedUrlRequest的AddHeader方法,将x-amz-checksum-sha256纳入签名范围:

var preSignRequest = new GetPreSignedUrlRequest
{
    BucketName = bucketName,
    Key = key,
    Verb = HttpVerb.PUT,
    Expires = DateTime.UtcNow.AddHours(1)
};
// 添加需要签名的校验和头
preSignRequest.AddHeader("x-amz-checksum-sha256", sha256ofFile);

string presignedUrl = amazonS3Client.GetPreSignedURL(preSignRequest);

生成后的URL允许请求携带该头,此时执行SimplePutAsync即可正常通过校验。

2. 使用Post预签名上传(对应generate_presigned_post)

.NET SDK提供GeneratePresignedPost方法,支持表单上传并指定校验和条件:

var postPolicy = new PostPolicy
{
    Bucket = bucketName,
    Key = key,
    Expires = DateTime.UtcNow.AddHours(1)
};
// 添加校验和匹配条件
postPolicy.Conditions.Add(new Condition("x-amz-checksum-sha256", sha256ofFile));

var presignedPost = amazonS3Client.GeneratePresignedPost(postPolicy);
// 后续可通过presignedPost.Url和presignedPost.FormFields构造表单上传请求

3. 利用additionalProperties参数传递校验和

GeneratePreSignedURL的additionalProperties参数可传入需要签名的自定义头或参数:

var additionalProps = new Dictionary<string, string>
{
    {"x-amz-checksum-sha256", sha256ofFile}
};

string presignedUrl = amazonS3Client.GeneratePreSignedURL(
    bucketName: bucketName,
    key: key,
    expiresIn: TimeSpan.FromHours(1),
    verb: HttpVerb.PUT,
    additionalProperties: additionalProps
);

该参数会将指定键值对纳入签名范围,确保请求携带对应值时签名验证通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:43:19