ASP. Net Core - загрузка файла EC2 в S3 с отказом в доступе - PullRequest
0 голосов
/ 27 февраля 2020

Я разработал. NET Core 3.1 Web API, который позволяет пользователям загружать свои документы в корзину S3. Когда я развертываю API в AWS ElasticBeansTalk EC2 и вызываю конечную точку, которая загружает файл на S3, я получаю сообщение об ошибке «Отказано в доступе».

Кстати, я создал политику и роль IAM для дать полный доступ к S3 из моего экземпляра EC2. Я также скопировал папку. aws, содержащую файл учетных данных, в экземпляр EC2.

Действие контроллера API

public async Task<ApiResponse> UpdateProfilePic([FromBody]UploadProfilePicRequest model)
{
    using (Stream stream = model.profilePicData.Base64StringToStream(out string header))
    {
        var tags = new List<KeyValuePair<string, string>>();
        var metaData = new List<KeyValuePair<string, string>>();
        metaData.Add(new KeyValuePair<string, string>("Content-Disposition", $"attachment; filename=\"{model.filename}\""));
        if (_host.IsDevelopment())
        {
            tags.Add(new KeyValuePair<string, string>("public", "yes"));
        }
        await AmazonS3Uploader.UploadFileAsync(stream, "myDir/", model.fileId, tags, metaData);
    }
}

AmazonS3Helper класс, показанный ниже:

using Amazon;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace UploderApp.Services
{
    public static class AmazonS3Uploader
    {

        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.APSouth1;

        private static readonly IAmazonS3 s3Client = new AmazonS3Client(GetAwsCredentials(), bucketRegion);
        private static readonly string S3Bucket = "abc-test";


        private static AWSCredentials GetAwsCredentials()
        {
            var chain = new CredentialProfileStoreChain();
            if (chain.TryGetAWSCredentials("MYPROFILE", out AWSCredentials awsCredentials))
            {
                return awsCredentials;
            }
            return null;
        }

        public static async Task UploadFileAsync(Stream fileStream, string virtualDirectory, string keyName)
        {
            try
            {
                using (var fileTransferUtility = new TransferUtility(s3Client))
                {
                    //Upload data from a type of System.IO.Stream.
                    await fileTransferUtility.UploadAsync(fileStream, S3Bucket, virtualDirectory + keyName).ConfigureAwait(true);
                }
            }
            catch (AmazonS3Exception e)
            {
                throw new Exception($"Error encountered on server. Message:'{e.Message}' when writing an object");
            }
        }

        public static async Task UploadFileAsync(Stream stream, string virtualDirectory, string keyName, List<KeyValuePair<string, string>> tags = null, List<KeyValuePair<string, string>> metadata = null)
        {
            try
            {
                // Specify advanced settings.
                var fileTransferUtilityRequest = new TransferUtilityUploadRequest
                {
                    BucketName = S3Bucket,
                    InputStream = stream,
                    StorageClass = S3StorageClass.Standard,
                    Key = virtualDirectory + keyName
                };
                if (metadata != null)
                {
                    foreach (var item in metadata)
                    {
                        fileTransferUtilityRequest.Metadata.Add(item.Key, item.Value);
                    }
                }
                if (tags != null)
                {
                    fileTransferUtilityRequest.TagSet = new List<Tag>();
                    foreach (var tag in tags)
                    {
                        fileTransferUtilityRequest.TagSet.Add(new Tag { Key = tag.Key, Value = tag.Value });
                    }
                }

                using (var fileTransferUtility = new TransferUtility(s3Client))
                {
                    await fileTransferUtility.UploadAsync(fileTransferUtilityRequest).ConfigureAwait(true);
                }

            }
            catch (AmazonS3Exception e)
            {
                throw new Exception($"Error encountered on server. Message:'{e.Message}' when writing an object");
            }
        }

    }

}

Однако, если я создаю консольное приложение и использую вышеупомянутый класс без каких-либо изменений, он загружает файл из того же экземпляра EC2.

Код из функции Main моего Консольного приложения.

    public static void Main()
    {   
        var file = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Screenshot.png";
        try
        {

            var tags = new List<KeyValuePair<string, string>>();
            var metaData = new List<KeyValuePair<string, string>>();
            metaData.Add(new KeyValuePair<string, string>("Content-Disposition", $"attachment; filename=\"profile-pic.png\""));

            using (var stream = new FileStream(file, FileMode.Open))
            {
                AmazonS3Uploader.UploadFileAsync(stream, "mydir/", "screenshot.png", tags, metaData).GetAwaiter().GetResult();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }           
    }

Это очень странно. Кто-нибудь может помочь мне понять причину root, пожалуйста?

Редактировать: 1 Вывод aws s3 ls s3://abc-test показан ниже enter image description here

Редактировать: 2 Загрузка папки EC2 в S3 Upload EC2 Folder to S3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...