Как я могу назначить bucket-owner-full-control при создании объекта S3 с помощью boto3? - PullRequest
0 голосов
/ 05 мая 2020

Я использую библиотеку Amazon boto3 в Python, чтобы загрузить файл в корзину другого пользователя. Политика сегмента, применяемая к сегменту других пользователей, настраивается следующим образом:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3BucketList",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::uuu"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::bbb"
        },
        {
            "Sid": "DelegateS3ObjectUpload",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::uuu"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::bbb",
                "arn:aws:s3:::bbb/*"
            ]
        }
    ]
}

, где uuu - это мой идентификатор пользователя, а bbb - имя сегмента, принадлежащего другому пользователю. Мой пользователь и другой пользователь являются учетными записями IAM, принадлежащими разным организациям . (Я знаю, что эту политику можно написать более просто, но цель состоит в том, чтобы добавить проверку загрузки для блокировки объектов без создания соответствующих разрешений).

Затем я могу использовать следующий код для перечисления всех объектов в ведро, а также для загрузки новых объектов в ведро. Это работает, однако владелец корзины не имеет доступа к объекту из-за того, что по умолчанию Amazons делают объекты закрытыми для создателя объекта

import base64
import hashlib
from boto3.session import Session


access_key = "value generated by Amazon"
secret_key = "value generated by Amazon"
bucketname = "bbb"

content_bytes = b"hello world!"
content_md5 = base64.b64encode(hashlib.md5(content_bytes).digest()).decode("utf-8")
filename = "foo.txt"

sess = Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key)

bucket = sess.resource("s3").Bucket(bucketname)
for o in bucket.objects.all():
    print(o)

s3 = sess.client("s3")
s3.put_object(
    Bucket=bucketname,
    Key=filename,
    Body=content_bytes,
    ContentMD5=content_md5,
    # ACL="bucket-owner-full-control"  # Uncomment this line to generate error
)

Как только я раскомментирую параметр ACL, код генерирует сообщение об ошибке Доступ запрещен. Если я перенаправляю это так, чтобы он указывал на корзину внутри моей собственной организации, опция ACL преуспевает, и владельцу корзины дается полное разрешение на объект.

Теперь я не могу понять это, тем более, что собственные советы амазонок, похоже, заключаются в том, чтобы делать это так, как я показал.

https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-owner-access/

https://aws.amazon.com/premiumsupport/knowledge-center/s3-require-object-ownership/

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Недостаточно иметь разрешение только в политиках корзины.

Проверьте, не указаны ли у вашего пользователя (или роли) s3:PutObjectAcl разрешение в IAM .

0 голосов
/ 05 мая 2020

При использовании методов resource в boto3 может выполняться несколько различных вызовов API, и не всегда очевидно, какие именно вызовы выполняются.

Для сравнения, при использовании client методов в boto3, между вызовом API, выполняемым в boto3, и вызовом API, полученным AWS.

, существует соответствие 1: 1. Поэтому вполне вероятно, что resource.put_object() метод вызывает дополнительный API, например PutObjectAcl. Вы можете подтвердить это, просмотрев AWS CloudTrail и посмотрев, какие вызовы API выполняются из вашего приложения.

В таком случае вам потребуется дополнительное разрешение s3:PutObjectAcl. Это может потребоваться, если процесс загрузки сначала создает объект, а затем обновляет список управления доступом объекта.

При использовании методов client для загрузки файла существует также возможность указать ACL, который, как мне кажется, применяется напрямую, а не требует второго вызова API. Таким образом, использование метода client для создания объекта, вероятно, не потребует этого дополнительного разрешения.

...