嗯,我找到了一个可能对你们中的某些人有用的“解决方法”。
首先,转到 Cognito 用户池并创建一个您选择的自定义属性,该属性将包含您的所有值。请记住,Cognito 的属性值限制为 2048 个字符。
我们称该属性为attribute_groups。将所有值作为带有您选择的分隔符的字符串放在那里。在我的情况下,user1 带有属性custom:attribute_groups = "123o789" 意味着user1 在逻辑上属于123 和789 组。
映射这些属性in Cognito Identity Pools。按照示例主体的标记键:groups 将从属性名称中选择:custom:attribute_groups。
最后,设置用户池中经过身份验证的用户所采用的 IAM 策略,如下所示。就我而言,我想允许群组123 列出s3://my_bucket/123,456 列出s3://my_bucket/456 等等。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my_bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"123/*"
],
"aws:PrincipalTag/groups": [
"*123*"
]
}
}
},
{
"Sid": "2",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my_bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"456/*"
],
"aws:PrincipalTag/groups": [
"*456*"
]
}
}
},
{
"Sid": "3",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my_bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"789/*"
],
"aws:PrincipalTag/groups": [
"*789*"
]
}
}
}
]
}
完成我的示例 - 当user1 获得他们的凭据时(您可以通过创建用户、设置其属性然后执行aws cognito-idp initiate-auth 来获取ID token,然后通过aws cognito-identity get-id 获取identity 来测试它最后aws cognito-identity get-credentials-for-identity 获取访问密钥ID/秘密访问密钥/会话令牌),他们可以执行aws s3 ls s3://my_bucket/123 和aws s3 ls s3://my_bucket/789。
很遗憾,这仍然受到以下因素的严重限制:
- IAM 政策字符数限制 (10240)
- Cognito 自定义属性长度限制 (2048)
通过这种精细的 IAM 策略,您最多可以拥有 15-20 个“组”。
您可能会以某种方式通过创建多个策略和多个(“假”)Cognito 用户池组来反击,让每个用户都附加到每个组,然后使用 ID token 中的 cognito:roles 属性遍历这些组并假设这些角色使用GetCredentialForIdentity,允许您设置CustomRoleArn。它可以工作(我已经检查过),但真的很hacky。
但是,有一个技巧可以将 Cognito 功能扩展到你们中的某些人并摆脱这个限制。要求是目录的结构是可预测的,并且您不需要访问子目录。我们将使用${s3:prefix} 也是一个变量这一事实。
如果是这样,您的政策可能如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my_bucket"
],
"Condition": {
"StringLike": {
"aws:PrincipalTag/groups": [
"*${s3:prefix}*"
]
}
}
},
{
"Sid": "2",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::my_bucket/${s3:prefix}/*"
],
"Condition": {
"StringLike": {
"aws:PrincipalTag/groups": [
"*${s3:prefix}*"
]
}
}
}
]
}
然后在custom:attribute_groups 中,您必须指定给定用户有权访问的所有前缀(即所有目录)。请注意,不允许他们访问这些目录的子目录,因为 ${s3:prefix} 会有所不同。
例如,用户:
custom:attribute_groups = directoryA####directoryA/subdirectoryAA####directoryC/subdirectoryCA/subsubdirectoryCAA
将被允许访问以下位置的文件:
my_bucket/directoryA
my_bucket/directoryA/subdirectoryAA
my_bucket/directoryC/subdirectoryCA/subsubdirectoryCAA
并且没有其他(子)目录! directoryA/subdirectoryAB 无法访问,尽管 directoryA 是。
当然,每个属性最多可以容纳 2048 个字符。但是您可以在 Cognito 中创建多达 50 个自定义属性并相应地扩展您的策略。我认为这对于大多数传统用例来说应该足够了。