问题描述
我想下载存储在 S3 中的多个图像。但是现在,如果我只能下载一个就足够了。我有对象路径的信息。
遇到错误***。消息:读取对象时“拒绝访问”...
我首先根据我的密钥和访问配置创建一个 AmazonS3Client 对象以连接到服务器,然后根据我的对象的存储路径创建一个请求,然后以某种方式读取数据并将其保存在我的设备中。
顺便说一下,在我们的 AWS S3 中,我们有“角色”,这意味着要从 Web 平台直接从 S3 下载,我在 AWS 中的用户不足以访问这些对象,我还应该将角色更改为在我登录后可以访问这些图像的角色。
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Threading.Tasks;
namespace Amazon.DocSamples.S3
{
class GetobjectTest
{
private const string bucketName = "My_Bucket_Name";
private const string keyName = "123/456/789.jpg";
// Specify your bucket region (an example region is shown).
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
private static IAmazonS3 client;
static string accessKey = "***AccessKey***"; // "YourAccessKeyHere";
static string secretKey = "***SecretKey***";
public static void Main()
{
client = new AmazonS3Client(accessKey,secretKey,bucketRegion);
ReadobjectDataAsync().Wait();
}
static async Task ReadobjectDataAsync()
{
string responseBody = "";
GetobjectRequest request = new GetobjectRequest
{
BucketName = bucketName,Key = keyName
};
using (GetobjectResponse response = awaitclient.GetobjectAsync(request))
using (Stream responseStream = response.ResponseStream)
using (StreamReader reader = new StreamReader(responseStream))
{
string title = response.Metadata["x-amz-Meta-title"]; // Assume you have "title" as medata added to the object.
string contentType = response.Headers["Content-Type"];
Console.WriteLine("Object Metadata,Title: {0}",title);
Console.WriteLine("Content type: {0}",contentType);
responseBody = reader.ReadToEnd(); // Now you process the response body.
}
}
}
}
我发现以下与访问问题相关的链接: https://aws.amazon.com/premiumsupport/knowledge-center/s3-troubleshoot-403/
解决方法
我稍微修改了您的代码,并且能够成功执行 GetObjectAsync 请求。
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using System.Drawing;
using System.Threading.Tasks;
namespace DownloadFromS3
{
class GetObjectTest
{
private static IAmazonS3 client;
private const string regionName = "us-west-2";
private const string accessKey = "accessKey";
private const string secretKey = "secretKey";
private const string roleSessionName = "roleSessionName";
private const string roleArn = "arn:aws:iam::123456789:role/yourRoleName";
private const string bucketName = "bucketName";
private const string keyName = "folder/keyName.jpg";
public static void Main(string[] args)
{
var assumeRoleCredentials = FetchAssumeRoleCredentials();
client = new AmazonS3Client(assumeRoleCredentials,RegionEndpoint.GetBySystemName(regionName));
ReadObjectDataAsync().Wait();
}
static async Task ReadObjectDataAsync()
{
var request = new GetObjectRequest()
{
BucketName = bucketName,Key = keyName,ResponseHeaderOverrides = new ResponseHeaderOverrides
{
ContentType = "image/jpg"
}
};
using (var response = await client.GetObjectAsync(request))
{
using (var bitmap = new Bitmap(response.ResponseStream))
{
bitmap.Save(@"C:\Image.jpg");
}
}
}
static Credentials FetchAssumeRoleCredentials()
{
var assumeRoleRequest = new AssumeRoleRequest
{
RoleSessionName = roleSessionName,RoleArn = roleArn
};
var securityTokenServiceClient = new AmazonSecurityTokenServiceClient(accessKey,secretKey,RegionEndpoint.GetBySystemName(regionName));
var assumeRoleResponse = securityTokenServiceClient.AssumeRoleAsync(assumeRoleRequest).Result;
return assumeRoleResponse.Credentials;
}
}
}
代码大致相同。我怀疑的是
- 正在使用的
regionName
值 AWS region code - 使用的 AWS 凭证没有足够的权限从 S3 读取数据
编辑:
- 更新了在本地保存图像的代码。 (确保设置必要的写入权限)
- 更新代码以使用 assumed role credentials 创建 S3 客户端。您的访问密钥和秘密密钥应有权访问代入角色,而代入角色应有权访问 S3 存储桶。