1

我希望下载存储在 S3 中的多个图像。但是现在我只下载一个就足够了。我有对象路径的信息。

当我运行以下代码时,我收到此错误:

遇到错误***。消息:读取对象时“拒绝访问”...

我首先根据我的密钥和访问配置创建一个AmazonS3Client对象以连接到服务器,然后根据我的对象的存储路径发出请求,然后以某种方式读取数据并将其保存在我的设备中。

顺便说一句,在我们的 AWS S3 中,我们有“<em>role”,这意味着要从 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/

4

1 回答 1

2

我对您的代码进行了一些修改,并且能够成功执行 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 区域代码
  • 使用的 AWS 凭证没有足够的权限从 S3 读取数据

编辑 :

  1. 更新代码以在本地保存图像。(确保设置必要的写入权限)
  2. 更新了使用假定角色凭据创建 S3 客户端的代码。您的访问密钥和密钥应有权访问代入角色,代入角色应有权访问 S3 存储桶。
于 2021-06-17T08:15:30.187 回答