.NET项目用AWSSDK.S3对接Cloudflare R2时出现签名不匹配问题
使用AWSSDK.S3对接Cloudflare R2时上传文件出现签名不匹配错误
对接Cloudflare R2时,调用PutObjectAsync上传文件报错:
The request signature we calculated does not match the signature you provided. Check your secret access key and signing method.
已确认凭证正确(能成功调用列表接口获取对象),但上传始终失败。
上传代码:
public async Task<string> UploadImageAsync(Stream fileStream, string fileName, string contentType) { var sanitizedFileName = fileName.Replace(" ", "_").Replace("/", "-"); var key = $"profile-images/{Guid.NewGuid()}-{sanitizedFileName}"; var request = new PutObjectRequest { BucketName = settings.Value.BucketName, Key = key, InputStream = fileStream, ContentType = contentType, DisablePayloadSigning = true }; await s3Client.PutObjectAsync(request); return $"{settings.Value.PublicUrl}/{key}"; }
客户端配置代码:
services.AddSingleton<IAmazonS3>(provider => { var settings = configuration.GetSection(CloudflareR2Settings.SectionName).Get<CloudflareR2Settings>(); var config = new AmazonS3Config { ServiceURL = $"https://1700ebc57525e0a0f6a5ff6f27d9***8.r2.cloudflarestorage.com", ForcePathStyle = true, UseHttp = false, AuthenticationRegion = "auto", LogMetrics = true, LogResponse = true }; var credentials = new BasicAWSCredentials(settings.AccessKey, settings.SecretKey); return new AmazonS3Client(credentials, config); });
期望实现文件成功上传。
解决步骤
- 移除或清空AuthenticationRegion设置
Cloudflare R2不使用AWS的区域概念,设置AuthenticationRegion = "auto"会导致签名计算时引入错误参数,需移除该配置或设为空字符串,同时显式指定签名版本为v4:
var config = new AmazonS3Config { ServiceURL = $"https://1700ebc57525e0a0f6a5ff6f27d9***8.r2.cloudflarestorage.com", ForcePathStyle = true, UseHttp = false, SignatureVersion = SignatureVersion.V4, LogMetrics = true, LogResponse = true };
- 重置文件流位置
上传前确保文件流的读取位置在起始处,避免因流内容读取不完整导致签名校验失败:
public async Task<string> UploadImageAsync(Stream fileStream, string fileName, string contentType) { var sanitizedFileName = fileName.Replace(" ", "_").Replace("/", "-"); var key = $"profile-images/{Guid.NewGuid()}-{sanitizedFileName}"; // 重置流到起始位置 fileStream.Position = 0; var request = new PutObjectRequest { BucketName = settings.Value.BucketName, Key = key, InputStream = fileStream, ContentType = contentType, DisablePayloadSigning = true }; await s3Client.PutObjectAsync(request); return $"{settings.Value.PublicUrl}/{key}"; }
- 验证DisablePayloadSigning兼容性
若上述步骤无效,可尝试关闭DisablePayloadSigning(移除该配置,默认值为false),让SDK完整计算payload签名,部分旧版本SDK与Cloudflare R2的payload签名跳过逻辑存在兼容性问题。
内容的提问来源于stack exchange,提问作者Nouralddin Abdullah
相关产品推荐
相关产品推荐

