Boto3: generate_presigned_url получает отказ в доступе во время загрузки

Я тестирую создание предварительно подписанного URL-адреса для загрузки файлов на S3. У меня нет проблем с созданием подписанного URL-адреса, но я получаю сообщение об ошибке AccessDenied при попытке загрузить его.

Я резюмировал свою проблему в следующем коде для тестирования.

Исходный код

import boto3
import os
s3 = boto3.client('s3')
def list_files():
    print("Listing files in bucket:")
    bucket = boto3.resource('s3').Bucket(bucket_name)
    for obj in bucket.objects.all():
        print(" - "+obj.key)

bucket_name = "asf-bucket"

list_files()

key= "test.py"
print (" Generating pre-signed url...")
url=s3.generate_presigned_url('put_object', Params = {'Bucket':bucket_name, 'Key':key}, ExpiresIn=3600, HttpMethod='PUT')
command = "curl --request PUT --upload-file {} {}".format(key, url)
print(command)
print (" Uploading with curl ...")
os.system(command)

Вывод сценария

$ python3 test.py
Listing files in bucket:
 - Dropped text.txt
 Generating pre-signed url...
curl --request PUT --upload-file test.py https://asf-bucket.s3.amazonaws.com/test.py?AWSAccessKeyId=----&Signature=----&Expires=----
 Uploading with curl ...
<?xml version = "1.0" encoding = "UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>A0E4587FFEB9F1EE</RequestId><HostId>kvfkV7YdDmtNNCSfWAjDTdZ/8+y2HrfcXSseQPlrq0300vjg9zYe1H0Qidsqf7kcBIieUGoXoUA=</HostId></Error>

Протестировано с корневой учетной записью AWS. У меня такая же ошибка.

CORS-конфигурация

<CORSConfiguration xmlns = "http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Что мне не хватает?

https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html

Обновление — добавление типа контента

Следуя совету @kichik, я добавил тип контента без изменений в текущем поведении.

url=s3.generate_presigned_url('put_object', Params = {'Bucket':bucket_name, 'Key':key, 'ContentType':'text/plain'}, ExpiresIn=3600, HttpMethod='PUT')
command = "curl --header \"Content-Type: text/plain\" --request PUT --upload-file {} {}".format(key, url)

Попробуйте установить Content-Type как в подписанном URL, так и в команде curl, чтобы они были одинаковыми.

kichik 03.04.2019 21:18

Проверено, и это не имело никакого эффекта

albert 04.04.2019 11:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
1 988
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Все было в порядке, ошибка заключалась не в экранировании URL-адреса в оболочке.

Итак, вместо

curl --request PUT --upload-file test.py https://asf-bucket.s3.amazonaws.com/test.py?AWSAccessKeyId=----&Signature=----&Expires=----

Делать

curl --request PUT --upload-file test.py 'https://asf-bucket.s3.amazonaws.com/test.py?AWSAccessKeyId=----&Signature=----&Expires=----'

Другие вопросы по теме

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