Lambda S3 getObject (запускается из ajax-вызова) выбрасывает 403 отказа - PullRequest
2 голосов
/ 31 октября 2019

У меня есть лямбда-функция, которая получает изображение из одного сегмента, изменяет его размер и помещает в другое. Лямбда-функция настроена на запуск при создании файла исходного блока. Довольно стандартный материал для учебного уровня.

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

Однако, когда я использую xhr из своего веб-приложения для помещения изображения в тот же контейнер, я получаю следующую ошибку (выдается из моего вызова s3.getObject):

AccessDenied: Access Denied
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:585:35

ИмеяОбширные поиски, большинство людей говорят, что 403 ошибки обычно сводятся к роли / политике разрешений для лямбда-функции. Но когда я траляю журналы, единственное различие, которое я вижу между моей загрузкой xhr и загрузкой веб-интерфейса aws, - это eventName и userIdentity.

Для загрузки веб-интерфейса это Put и PrincipalId:

eventName: 'ObjectCreated:Put',
userIdentity: { principalId: 'AWS:AIDAJ2VMZPNX5NJD2VBLM' }

Но при вызове xhr это сообщение и аноним:

eventName: 'ObjectCreated:Post',
userIdentity: { principalId: 'Anonymous' }

Моя роль Lambda имеет две политики:

AWSLambdaExecute

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:*"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}

AWSLambdaBasicExecutionRole

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

Мои корзины S3 имеют следующие политики:

Исходная корзина:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::source-bucket-name/*"
        },
        {
            "Sid": "All on bucket by lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::source-bucket-name"
        }
    ]
}

Целевая корзина:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::destination-bucket-name/*"
        },
        {
            "Sid": "All on bucket by lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::destination-bucket-name"
        }
    ]
}

Нужно ли как-то передавать(или назначить) идентификатор участника для моего вызова xhr, чтобы он заработал? Или мне нужно добавить разрешения / политики / роли к моей функции, чтобы она могла запускать функцию без основного идентификатора, привязанного к триггеру?

РЕДАКТИРОВАТЬ: Вот код JS, который отправляет файл POST в файлисходное ведро:

function uploadFileAttachment(attachment, form) {

  var formButtons = document.querySelectorAll("form.form--trix button.btn");

  formButtons.forEach((button) => {
    button.setAttribute("disabled", "disabled");
  });

  uploadFile(attachment.file, setProgress, setAttributes)

  function setProgress(progress) {
    attachment.setUploadProgress(progress)
  }

  function setAttributes(attributes) {

    attachment.setAttributes(attributes)

    formButtons.forEach((button) => {
      button.removeAttribute("disabled");
    });

  }
}

function uploadFile(file, progressCallback, successCallback) {

  var key = createStorageKey(file)
  var formData = createFormData(key, file)
  var xhr = new XMLHttpRequest()

  xhr.open("POST", global.s3url, true)

  xhr.upload.addEventListener("progress", function(event) {
    var progress = event.loaded / event.total * 100
    progressCallback(progress)
  })

  xhr.addEventListener("load", function(event) {
    if (xhr.status == 204) {
      var attributes = {
        url: global.s3url + key,
        href: global.s3url + key + "?content-disposition=attachment"
      }
      successCallback(attributes)
    }
  })

  xhr.send(formData);
}

function createStorageKey(file) {
  var date = new Date()
  var day = date.toISOString().slice(0,10)
  var name = date.getTime() + "-" + file.name
  return [ "trix", day, name ].join("/")
}

function createFormData(key, file) {
  var data = new FormData()
  data.append("key", key)
  data.append("Content-Type", file.type)
  data.append("file", file)
  return data
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...