gpt4 book ai didi

amazon-web-services - 如何使用 boto3 删除受 MFA 保护的存储桶上的 S3 对象/版本?

转载 作者:行者123 更新时间:2023-12-05 04:47:58 24 4
gpt4 key购买 nike

我有一个名为 protected-bucket 的版本化 S3 存储桶,我想以编程方式删除对象或版本(有时只是一些版本)。 Bucket 附加了以下策略,强制执行 Delete* 操作时出现 MFA:

{
"Sid": "RequireMFAForDelete",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:Delete*",
"Resource": "arn:aws:s3:::protected-bucket/*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "false"
}
}
}

我还尝试按照 https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-7 页面上的建议,在存储桶策略中使用 "Condition": { "Null": { "aws:MultiFactorAuthAge": true }}。从下面得到同样的问题......

这是一个最小的 Python3 代码,应该删除我上面提到的存储桶中的对象版本:

#!/usr/bin/env python3
import boto3
from datetime import datetime


mfa_totp = input("Enter the MFA code: ")

session_name='my-test-session-' + str(int(datetime.utcnow().timestamp()))
client=boto3.client('sts', 'us-east-1')
ar_res = client.assume_role(
RoleArn='arn:aws:iam::123456789102:role/test-role',
RoleSessionName=session_name,
DurationSeconds=900,
SerialNumber='arn:aws:iam::987654321098:mfa/my_user_name',
TokenCode=mfa_totp,
)
print(ar_res)
tmp_creds = ar_res["Credentials"]

s3_client = boto3.client("s3", "us-east-1",
aws_access_key_id=tmp_creds["AccessKeyId"],
aws_secret_access_key=tmp_creds["SecretAccessKey"],
aws_session_token=tmp_creds["SessionToken"])

s3_bucket = "protected-bucket"
s3_key = "test/test4.txt"
s3_version = "XYZXbHbi3lpCNlOM8peIim6gi.IZQJqM"

# If I put code here that lists objects in
if s3_version:
response = s3_client.delete_object(Bucket=s3_bucket,
Key=s3_key,
VersionId=s3_version)
else:
response = s3_client.delete_object(Bucket=s3_bucket,Key=s3_key)

print(response)

我得到的错误如下:

Traceback (most recent call last):
File "./del_test.py", line 37, in <module>
response = s3_client.delete_object(Bucket=s3_bucket,
File "/home/dejan/py/myproj/lib64/python3.8/site-packages/botocore/client.py", line 386, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/home/dejan/py/myproj/lib64/python3.8/site-packages/botocore/client.py", line 705, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied

注意事项:

  • 我假设的角色是一个不同的帐户(有些人可能已经注意到 Python 代码中的不同帐号。
  • 该角色具有附加到该角色的策略中允许的删除*操作。当我删除存储桶策略中的 MFA 保护时,上面的 Python 3 代码可以工作 - 它可以删除对象和版本。

最佳答案

原来我错过了https://docs.amazonaws.cn/en_us/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html文档中给出的关键信息:

The temporary credentials returned by AssumeRole do not include MFA information in the context, so you cannot check individual API operations for MFA. This is why you must use GetSessionToken to restrict access to resources protected by resource-based policies.

简而言之,如果我只是 assume_role(),with MFA,就像我在问题中提供的 Python 代码中所做的那样,MFA 数据将不会传递下去,因此 get_session_token() 是一个必须...遵循重构代码(在我的同事@Chadwick 的帮助下制作)按预期工作:

#!/usr/bin/env python3
import boto3
from datetime import datetime


mfa_serial = "arn:aws:iam::987654321098:mfa/my_user_name"
role_to_assume = "arn:aws:iam::123456789102:role/test-role"

mfa_totp = input("Enter the MFA code: ")
mfa_sts_client = boto3.client("sts", "us-east-1")
mfa_credentials = mfa_sts_client.get_session_token(
SerialNumber=mfa_serial,
TokenCode=mfa_totp,
)["Credentials"]

session_name='my-test-session-' + str(int(datetime.utcnow().timestamp()))
# We now create a client with credentials from the MFA enabled session we created above:
ar_sts_client=boto3.client("sts", "us-east-1",
aws_access_key_id=mfa_credentials["AccessKeyId"],
aws_secret_access_key=mfa_credentials["SecretAccessKey"],
aws_session_token=mfa_credentials["SessionToken"])
ar_res = ar_sts_client.assume_role(
RoleArn=role_to_assume,
RoleSessionName=session_name,
DurationSeconds=900
)
print(ar_res)
tmp_creds = ar_res["Credentials"]

s3_client = boto3.client("s3", "us-east-1",
aws_access_key_id=tmp_creds["AccessKeyId"],
aws_secret_access_key=tmp_creds["SecretAccessKey"],
aws_session_token=tmp_creds["SessionToken"])


s3_bucket = "protected-bucket"
s3_key = "test/test4.txt"
s3_version = "YYFMqnLaVEosoZ1Zk3Xy8dVbNGQVEF35"
# s3_version = None

if s3_version:
response = s3_client.delete_object(Bucket=s3_bucket,
Key=s3_key,
VersionId=s3_version)
else:
response = s3_client.delete_object(Bucket=s3_bucket,Key=s3_key)

print(response)

关于amazon-web-services - 如何使用 boto3 删除受 MFA 保护的存储桶上的 S3 对象/版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68273891/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com