【发布时间】:2015-09-09 23:21:33
【问题描述】:
我正在尝试将我的所有 AWS Cognito 用户限制在我的 S3 存储桶中他们自己的子目录中。
我不希望他们在我更大的存储桶中列出、读取或写入其他人的子目录/文件,我只希望他们在自己的目录中读取和写入对象。
我正在汲取灵感from this AWS documentation snippet。
这是我的政策:
{
"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 检索到的访问/秘密/安全令牌三倍,使用 Cognito 令牌创建 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>
所以仍然不清楚为什么这不起作用。
【问题讨论】:
-
您能否澄清更改后的问题是什么?与原始问题相同(您可以访问子文件夹下的任何键)还是其他问题?
-
是的,同样的问题。当我的
GetObject和PutObject访问权限应仅限于用户文件夹时,我可以访问任何密钥。此外,我能够列出整个存储桶中的所有对象,而不仅仅是具有指定前缀的对象。 -
您的存储桶策略中是否有任何特殊内容允许比您的角色更多的访问权限?除了您在此处列出的角色之外,您是否有附加到该角色的其他策略?
-
如果您在我们的论坛上发帖或以其他方式向我们提供您的帐户 ID,我们还可以查看您的帐户详细信息并进行更仔细的调试。
-
@BobKinney:据我所知,我的存储桶中没有其他角色,也没有什么特别之处。不过肯定有问题。
标签: python amazon-web-services amazon-s3 boto amazon-cognito