AWS S3 getSignedUrl для объекта put возвращает 403 - PullRequest
1 голос
/ 22 февраля 2020

Я пытаюсь получить предварительно подписанный URL для загрузки файлов в корзину S3. Вот мой рабочий процесс:

1. Вызвать лямбду -> 2. Получить предварительно подписанный URL -> 3. Нажмите URL (PUT) с файлом

1. Вызвать лямбду

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

AWS.config.update({
  accessKeyId: '*****************',
  secretAccessKey: '*****************',
  region: 'us-east-1',
  signatureVersion: 'v4'
});

let requestObject = JSON.parse(event["body"]);
let fileName = requestObject.fileName;
let fileType = requestObject.fileType;
const myBucket = 'jobobo-resumes';

s3.getSignedUrl('putObject', {
"Bucket": myBucket,
"Key": fileName,
"ContentType": fileType
}, function (err, url) {

  if (err) {    
  mainCallback(null, err);
  } else {    
  mainCallback(null, url);    
  }

}

Итак, я получаю имя файла, тип файла (MIME) из запроса и использую его для создания подписи.

2. Получить предварительно подписанный URL Когда я нажимаю лямбду, я получаю предварительно подписанный URL. Теперь я буду использовать этот URL для загрузки файла на S3.

Getting pre-signed URL

3. Нажмите на URL-адрес (PUT) с помощью файла

Теперь я нажимаю URL-адрес с помощью метода HTTP и добавляю файл (двоичный файл), см. Мой запрос почтальона:

enter image description here

Вы видите, что я обработал запрос с помощью PUT HTTP-метода. Я получаю ошибку 403. Вот заголовки в запросе, и вы можете видеть, что тип контента равен image/jpeg:

enter image description here

Когда я пытаюсь POST метод, я получаю, что подпись недействительна. Я предполагаю, что это из-за подписи для метода PUT.

enter image description here

Вот настройки S3-корзины:

Так как Я получаю отказ в доступе, я полностью открыл ведро, я имею в виду Block Public access: off.

enter image description here

Что не так с настройками? Может S3?

1 Ответ

2 голосов
/ 23 февраля 2020

У вас есть сервисный объект в переменной s3, но вы не показываете в своем коде, где этот объект был построен ... но он выглядит как до , когда вы вызываете AWS.config.update() который задним числом не реконфигурирует ваш s3 объект. Порядок этих операций является проблемой.

Обновления, которые вы вносите в глобальный AWS.config объект, не применяются к ранее созданным сервисным объектам.

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/global-config-object.html

Если вы внимательно наблюдаете за созданным URL-адресом, вы можете видеть, что учетные данные Lambda Execution Role действительно используются, поэтому доступ запрещен.

Недостатки в том, что AWSAccessKeyId в URL не ваш, это ключ сеанса, начинающийся с ASIA вместо AKIA, как обычный идентификатор ключа доступа. Кроме того, есть токен сеанса x-amz-security-token, которого не будет в URL-адресе, созданном с учетными данными stati c. Также этот URL-адрес является подписью V2, поэтому, когда вы исправите проблему с настройкой учетных данных, формат подписанного URL-адреса будет значительно изменен. URL подписи V4 имеют X-Amz-Credential вместо AWSAccessKeyId.

...