[英]Specifying IAM roles for permissions in AWS S3
我試圖將我的所有AWS Cognito用戶限制為他們在S3存儲桶中自己的子目錄。
我不希望它們在我的較大存儲桶中列出,讀取或寫入其他人的子目錄/文件,而我只希望它們在自己的目錄中讀取和寫入對象。
我從這個AWS文檔片段中汲取了靈感。
這是我的政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"subfolder/"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::my-bucket/subfolder/${cognito-identity.amazonaws.com:sub}",
"arn:aws:s3:::my-bucket/subfolder/${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
我的代碼使用user_id = test@test.com
來檢索某個用戶的文件,但實際上允許我檢索受限制的文件:
import boto
# These keys are *not* hardcoded, I'm just leaving out
# the auth flow to get them from Cognito/STS as described
# here: https://mobile.awsblog.com/post/Tx2FL1QAPDE0UAH/Understanding-Amazon-Cognito-Authentication-Part-2-Developer-Authenticated-Ident
conn = boto.s3.connect_to_region('us-east-1',
aws_access_key_id=ACCESS_KEY_FROM_COGNITO,
aws_secret_access_key=SECRET_KEY_FROM_COGNITO,
security_token=SECURITY_KEY_FROM_COGNITO)
# get the bucket
b = conn.get_bucket('my-bucket', validate=False)
# try to get an object we SHOULD be able to get
k = Key(b)
k.key = 'subfolder/us-east-1:xxxx-xxxx-xxxx-xxxxxxxxx/foobar'
print "Contents:", k.get_contents_as_string() # success!
# try to get and object we SHOUDN'T be able to get
k2 = Key(b)
k2.key = 'subfolder/BLAH_BLAH/restricted'
print "Contents:", k2.get_contents_as_string() # should fail, but doesn't
不幸的是,我可以訪問和讀取兩個文件的內容,但是我遵循的是AWS博客文檔中的完全相同的模式。 我也不確定為什么在boto連接中需要validate=False
,但它似乎工作得很好。
我想念什么?
編輯:為響應下面的答案,我嘗試將我的角色更新為以下內容,但沒有任何區別:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"subfolder/${cognito-identity.amazonaws.com:sub}/*"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::my-bucket/subfolder/${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
我還通過使用通過Cognito令牌從STS檢索的訪問/秘密/安全令牌三重創建了boto
IAMConnection
對象,並查詢了我的角色名稱,以確認我正在使用的訪問憑據來自Cognito。為我的身份池識別用戶。 這樣做時,嘗試讀取此角色時遇到了以下異常(這正是我沒有授予訪問權限而應該發生的情況):
BotoServerError: BotoServerError: 403 Forbidden
<ErrorResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<Error>
<Type>Sender</Type>
<Code>AccessDenied</Code>
<Message>User: arn:aws:sts::MY_AWS_ACCT_ID:assumed-role/my_policy_role_name/session_name_here is not authorized to perform: iam:GetRole on resource: role awsNameFor_Role_Given_123012313</Message>
</Error>
<RequestId>xxx-xxxx-xxxx-xxxx-xxxxx</RequestId>
</ErrorResponse>
因此,仍然不清楚為什么它不起作用。
5件事:
答案很愚蠢。 顯然,S3中的存儲桶本身具有自己的策略(它們相當隱蔽),但是我有以下指令:
Principal: "*"
這使得存儲桶在世界范圍內都可以讀取。
第二個啟示是,如果使用帶有Condition
的s3:ListBucket
限制存儲桶,這並不意味着如果您列出存儲桶,則只會得到那些結果-必須按名稱調用它。 以boto
為例:
wrong = bucket.list() # will simply 403
right = bucket.list(prefix="base/subdir/<cognito-id>/") # will succeed
換句話說,S3的設計使您必須知道所需文件夾的前綴鍵,無論如何這都是一種好習慣。
我必須說,AWS的人員在這里和在他們的論壇上診斷此問題的幫助給我留下了深刻的印象。 無論如何,現在對S3有了更好的了解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.