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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:33:47