使用AWS SDK向DigitalOcean Spaces传图遇Forbidden错误求助
使用AWS SDK向DigitalOcean Spaces上传图片时返回Forbidden错误
Error making request with Error Code Forbidden and Http Status Code Forbidden. No further error information was return.
问题代码
public async Task<bool> AddUserImage(ImageCreateDTO imageCreateDto) { try { var credentials = new BasicAWSCredentials(_storageOptions.Value.AccessKey, _storageOptions.Value.SecretKey); AmazonS3Config config = new() { ServiceURL = _storageOptions.Value.ServiceUrl, }; AmazonS3Client s3Client = new( _storageOptions.Value.AccessKey, _storageOptions.Value.SecretKey, config ); using var stream = imageCreateDto.File.OpenReadStream(); TransferUtility fileTransferUtility = new(s3Client); TransferUtilityUploadRequest fileTransferUtilityRequest = new() { BucketName = $"joinorcreate/{_storageOptions.Value.UserImages}", StorageClass = S3StorageClass.Standard, PartSize = imageCreateDto.File.Length, Key = imageCreateDto.FileName, CannedACL = S3CannedACL.PublicRead, InputStream = stream }; // Add the x-amz-acl header fileTransferUtilityRequest.Headers["x-amz-acl"] = "public-read"; await fileTransferUtility.UploadAsync(fileTransferUtilityRequest); // PutObjectRequest request = new() // { // BucketName = $"joinorcreate/{_storageOptions.Value.UserImages}", // Key = imageCreateDto.FileName, // InputStream = stream, // ContentType = imageCreateDto.File.ContentType, // CannedACL = S3CannedACL.PublicRead, // StorageClass = S3StorageClass.Standard, // }; // await s3Client.PutObjectAsync(request); return true; } catch (AmazonS3Exception e) { Console.WriteLine(e.Message); return false; } catch (Exception e) { Console.WriteLine(e.Message); return false; } }
需求
- 解决上传时的Forbidden错误
- 设置图片上传后默认权限为公开可读
错误修复及配置方案
1. 修正核心配置问题
检查凭证权限
确认你的DigitalOcean Spaces Access Key和Secret Key有效,且该密钥拥有写入(Write)和编辑权限(Edit Permissions)。在DigitalOcean控制台的Spaces页面,进入对应空间的API密钥管理界面,验证权限配置。
完善AmazonS3Config配置
DigitalOcean Spaces需要指定正确的区域并禁用路径样式访问,修改配置如下:
AmazonS3Config config = new() { ServiceURL = _storageOptions.Value.ServiceUrl, // 格式示例:https://nyc3.digitaloceanspaces.com ForcePathStyle = false, // 必须设置为false,适配DigitalOcean的域名格式 RegionEndpoint = RegionEndpoint.GetBySystemName("nyc3") // 替换为你的Spaces所在区域,如sfo3、ams3等 };
修正BucketName格式
DigitalOcean的BucketName仅为你的Spaces名称,目录结构需通过Key参数实现,而非拼接在BucketName中:
TransferUtilityUploadRequest fileTransferUtilityRequest = new() { BucketName = "joinorcreate", // 直接使用Spaces名称 StorageClass = S3StorageClass.Standard, PartSize = imageCreateDto.File.Length, Key = $"{_storageOptions.Value.UserImages}/{imageCreateDto.FileName}", // 目录路径+文件名 CannedACL = S3CannedACL.PublicRead, InputStream = stream };
移除重复ACL设置
已通过CannedACL = S3CannedACL.PublicRead设置公开权限,无需手动添加x-amz-acl头,删除以下代码:
// fileTransferUtilityRequest.Headers["x-amz-acl"] = "public-read";
2. 确保图片默认公开的两种方式
- 代码层面:保持
CannedACL = S3CannedACL.PublicRead配置,每次上传时自动设置文件为公开可读。 - 控制台层面:在DigitalOcean控制台进入对应Spaces的设置页面,修改Default ACL为Public Read,此后所有新上传的文件默认权限均为公开,无需在代码中重复设置。
内容的提问来源于stack exchange,提问作者strofc
相关产品推荐
相关产品推荐

