Почему я не могу читать и писать в Amazon S3 из приложения Delphi VCL? - PullRequest
1 голос
/ 14 апреля 2020

Я создал приложение Delphi, из которого я хочу читать и писать из корзины Amazon S3 (простой сервис хранения).

В консоли управления S3 я создал новое ведро и установил Блокировать все публичные c доступ к Вкл.

Затем я создал нового пользователя для IAM (управление идентификацией и доступом) и предоставил этому пользователю привилегии AmazonS3FullAccess (на данный момент). В моем приложении я добавил компонент TAmazonConnectionInfo в свой проект и установил для свойства AccountKey секретный ключ доступа, а для свойства AccountName - идентификатор ключа своей учетной записи этого пользователя IAM.

В моем коде я создаю экземпляр Класс TAmazonStorageService, передав ему объект TAmazonConnectionInfo в конструкторе. Затем я вызываю метод UploadObject, которому я передаю имя сегмента, имя объекта и TArray, который содержит объект, который я хочу сохранить. Вызов UploadObject возвращает False. Я пробовал несколько разных байтовых массивов, в том числе один на основе примера, показанного в одном из видео YouTube, на которое я ссылался в нижней части этого поста, поэтому я почти уверен, что это не проблема с объектом, которым я являюсь пытаюсь сохранить.

Я попытался установить для параметра Блокировать доступ всех пользователей c значение Выкл., но это не решило проблему. Я не знаю, сколько потребуется времени, чтобы эти настройки вступили в силу, но после получаса не было различий в результате.

Либо я недостаточно настроил свой объект TAmazonConnectionInfo, либо есть один или больше объектов, которые мне нужно добавить в проект, или некоторая конфигурация, которую мне нужно выполнить в корзине.

Одна из проблем, с которыми я сталкиваюсь, заключается в том, что мое ведро S3 находится в восточной части США (штат Огайо). Свойство Region компонента TAmazonConnectionInfo установлено в amzrUSEast1, но я не уверен, что это правильно. Я попытался установить Region для amzrNotSpecified, но это не решило проблему.

Также я попытался установить StorageEndPoint для s3.us-east-2.amazon aws .com (http) и s3-accesspoint. us-east-2.amazon aws .com (https), основываясь на комментариях Павла.

Я исчерпал свои возможности. Если вы успешно работаете с ведрами S3 из Delphi, я был бы признателен, если бы вы помогли мне указать правильное направление.

Я использую Delphi Rio 10.3.3 на Windows 10 64-битных

Ссылки:

https://www.youtube.com/watch?v=RUT9clew4PM&t=396s

https://www.youtube.com/watch?v=rtZkVAOvavU&t=1582s

https://www.youtube.com/watch?v=8VjTEtK_VaM&list=PLwUPJvR9mZHg3YgQKG8QCJAqdNxZyDVfg&index=50&t=0s

1 Ответ

1 голос
/ 15 апреля 2020

Код ниже работает. Вставьте свои значения для AccountName, AccountKey и BucketName и попробуйте. Если произойдет сбой, сообщите нам, что он возвратил для вашего ответа.

Чтобы проверить это, я создал новое ведро с настройками по умолчанию: регион Восток США (Огайо) us-east-2 и заблокировал все публикации c доступ проверен. Я создал нового пользователя с доступом programmati c и назначил ему политику AmazonS3FullAccess.

Во время первоначального теста я получил ответ 400, который был разрешен путем установки StorageEndpoint:

400: Bad Request - заголовок авторизации искажен; регион 'us-east-1' неправильный; ожидая «us-east-2» (AuthorizationHeaderMalformed)

Если вы получите ответ 403, как показано ниже, убедитесь, что политика пользователя (или как вы настроили свои разрешения) установлена ​​правильно, и что Ваш AccountName и AccountKey верны.

403: запрещено

program AmazonS3test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Data.Cloud.CloudAPI, Data.Cloud.AmazonAPI, System.Classes;

const
  AccountName = ''; // IAM user Access key ID
  AccountKey = ''; // IAM user Secret access key
  BucketName = ''; // S3 bucket name
  StorageEndpoint = 's3-us-east-2.amazonaws.com';  // s3-<bucket region>.amazonaws.com
  ObjectName = 'TestFile.txt';
  MyString = 'Testing 1 2 3';

var
  ResponseInfo: TCloudResponseInfo;
  ConnectionInfo: TAmazonConnectionInfo;
  StorageService: TAmazonStorageService;
  StringStream: TStringStream;

begin
  ReportMemoryLeaksOnShutdown := True;

  ConnectionInfo := TAmazonConnectionInfo.Create(nil);
  StorageService := TAmazonStorageService.Create(ConnectionInfo);
  ResponseInfo := TCloudResponseInfo.Create;
  StringStream := TStringStream.Create(MyString);

  try
    try
      ConnectionInfo.AccountName := AccountName;
      ConnectionInfo.AccountKey := AccountKey;
      ConnectionInfo.StorageEndpoint := StorageEndpoint;

      StorageService.UploadObject(BucketName, ObjectName,
        StringStream.Bytes, True, nil, nil, amzbaPrivate, ResponseInfo);

      WriteLn('StatusCode: ' + IntToStr(ResponseInfo.StatusCode));
      WriteLn('Status    : ' + ResponseInfo.StatusMessage);
    except
      on E: Exception do
        WriteLn(E.ClassName, ': ', E.Message);
    end;
  finally
    StringStream.Free;
    ResponseInfo.Free;
    StorageService.Free;
    ConnectionInfo.Free;
  end;
end.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...