Cosss
@Cosss
Графический дизайнер

AWS S3 ошибка Access Denied при попытке загрузить файлы напрямую через pre-signed POST. Куда копать?

Пытаюсь сделать загрузку файлов в облако, минуя свой сервер.
Вот код на php:
<?php

require '../vend/vendor/autoload.php';
use Aws\S3\S3Client;  
use Aws\S3\Exception\S3Exception;

$bucket = '***';
$IAM_KEY = '***';
$IAM_SECRET = '***';

try {
    $s3 = S3Client::factory(
        array(
            'credentials' => array(
                'key' => $IAM_KEY,
                'secret' => $IAM_SECRET
            ),
            'version' => 'latest',
            'region'  => 'us-east-1'
        )
    );
} catch (Exception $e) {
    die("Error: " . $e->getMessage());
}

$formInputs = ['acl' => 'public-read'];
$options = [
    ['acl' => 'public-read'],
    ['bucket' => $bucket],
    ['starts-with', '$key', ''],
];
$expires = '+2 hours';

$postObject = new \Aws\S3\PostObjectV4(
    $s3,
    $bucket,
    $formInputs,
    $options,
    $expires
);

$formAttributes = $postObject->getFormAttributes();

$formInputs = $postObject->getFormInputs();

?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Aws S3 Direct File Uploader</title>
</head>
<body>

<form action="<?= $formAttributes['action'] ?>" method="post" enctype="multipart/form-data">
<?php
    foreach ($formInputs as $key => $value) {
        echo "<input type='hidden' name='$key' value='$value' />";
    }
?>
<input type="file" name="file" />
<input type="submit" value="Upload File" />
</form>


CORS config:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
      <CORSRule>
          <AllowedOrigin>*</AllowedOrigin>
          <AllowedMethod>GET</AllowedMethod>
          <AllowedMethod>POST</AllowedMethod>
          <AllowedMethod>PUT</AllowedMethod>
          <MaxAgeSeconds>3000</MaxAgeSeconds>
          <AllowedHeader>*</AllowedHeader>
      </CORSRule>
</CORSConfiguration>


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


После того как форма засабмичена выдается ошибка в XML:
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>1A71B86B340FAB93</RequestId>
  <HostId>
    4ve5duEAF5ph+o7Y57JapqU3kzqZzDEWEF6Lrb64lGY2jCZobGB19z06fXRXxI+GzmQRA83o/FU=
  </HostId>
</Error>


Хочу уточнить важный момент: я пробовал сделать обычную загрузку с теми же credentials через putObject() и все проходило нормально, объект создавался в бакете. Так же через getObject() получалось скачивать объекты. Подскажите куда копать, испробовал уже все, гугл не помогает.
  • Вопрос задан
  • 6421 просмотр
Решения вопроса 1
inoise
@inoise Куратор тега PHP
Solution Architect, AWS Certified, Serverless
По тому что кто-то забыл что если ставишь ACL на объект то надо и права на это выдавать)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
        }
    ]
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы