使用ASP.NET Core Web API上传文件至Cloudflare R2遇签名错误求助
使用AWSSDK上传文件到Cloudflare R2的签名问题解决思路
我开发了一个ASP.NET Core Web API项目,尝试通过AWSSDK将文件上传至Cloudflare R2,但遇到了签名相关的错误。
现有代码
using Amazon.Runtime; using Amazon.S3; using Amazon.S3.Model; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; namespace xxx.API.Controllers { [ApiController] [Route("api/[controller]")] [AllowAnonymous] public class CloudflareR2Controller { private readonly IAmazonS3 _s3Client; public CloudflareR2Controller(IConfiguration configuration) { string accessKeyId = "aaa"; string secretAccessKey = "bbb"; string serviceUrl = "https://ccc.r2.cloudflarestorage.com"; AWSCredentials credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey); AmazonS3Config config = new AmazonS3Config { ServiceURL = serviceUrl }; _s3Client = new AmazonS3Client(credentials, config); } [HttpPut("objects/{bucketName}")] public async Task<IActionResult> UploadObject(string bucketName, [FromBody] string filePath) { try { PutObjectRequest request = new PutObjectRequest { FilePath = @filePath, BucketName = bucketName, ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256 }; PutObjectResponse response = await _s3Client.PutObjectAsync(request); Console.WriteLine("ETag: {0}", response.ETag); //await _cloudflareR2Client.UploadObject(filePath, bucketName); return Ok(response); } catch (Exception ex) { return StatusCode(500, "Error: " + ex.Message); } } private IActionResult StatusCode(int v1, string v2) { throw new NotImplementedException(); } [HttpGet] public virtual OkObjectResult Ok([ActionResultObjectValue] object? value) => new OkObjectResult(value); [HttpGet("presigned-url/{bucketName}/{objectKey}")] public IActionResult GeneratePresignedUrl(string bucketName, string objectKey) { try { //_cloudflareR2Client.GeneratePresignedUrl(bucketName, objectKey); return Ok(bucketName); } catch (Exception ex) { return StatusCode(500, "Error: " + ex.Message); } } } }
遇到的第一个错误
"STREAMING-AWS4-HMAC-SHA256-PAYLOAD not implemented"
尝试修改后的代码
PutObjectRequest request = new PutObjectRequest { FilePath = @filePath, BucketName = bucketName, DisablePayloadSigning=true, //新增代码 ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256 };
修改后出现的新错误
{Please use "STREAMING-AWS4-HMAC-SHA256-PAYLOAD"}
解决思路与替代方案
1. 调整S3客户端配置,适配R2的签名要求
Cloudflare R2仅支持AWS v4签名,且需要指定兼容区域,同时强制路径样式访问。修改AmazonS3Config的配置:
AmazonS3Config config = new AmazonS3Config { ServiceURL = serviceUrl, SignatureVersion = "v4", RegionEndpoint = RegionEndpoint.USEast1, // R2兼容us-east-1区域 ForcePathStyle = true // R2要求使用路径样式访问 };
2. 改用文件流上传,避免FilePath的签名问题
直接使用FilePath上传时,AWSSDK可能无法正确处理流式签名。改用InputStream传入文件流:
[HttpPut("objects/{bucketName}")] public async Task<IActionResult> UploadObject(string bucketName, [FromBody] string filePath) { try { var fileName = Path.GetFileName(filePath); using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { PutObjectRequest request = new PutObjectRequest { InputStream = fileStream, BucketName = bucketName, Key = fileName, ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256 }; var response = await _s3Client.PutObjectAsync(request); Console.WriteLine("ETag: {0}", response.ETag); return Ok(response); } } catch (Exception ex) { return StatusCode(500, "Error: " + ex.Message); } }
3. 修复控制器的基础方法实现
当前控制器未继承ControllerBase,导致自定义的StatusCode和Ok方法存在问题。修改控制器定义:
public class CloudflareR2Controller : ControllerBase
这样可以直接使用框架内置的StatusCode、Ok等方法,无需自行实现。
4. 替代方案:使用Cloudflare官方工具
如果AWSSDK的兼容问题无法解决,可以直接使用Cloudflare官方提供的API或SDK(如Cloudflare.NET)进行文件上传,完全适配R2的特性。
内容的提问来源于stack exchange,提问作者fbdev1907
相关产品推荐
相关产品推荐

