Cognito身份池-使用"动态"属性进行基于属性的访问控制 [英] Cognito Identity Pools - Attribute-based access control with "dynamic" attributes

查看:18
本文介绍了Cognito身份池-使用"动态"属性进行基于属性的访问控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Cognito用户池中有数百个S3存储桶和几十个用户。我希望能够选择哪个用户可以访问哪个S3存储桶,例如:

  • user_a可以访问bucket_1bucket_2bucket_3
  • user_b可以访问bucket_2
  • user_c可以访问bucket_1bucket_4

以此类推。

我希望能够做到这一点,而无需创建创建动态策略的专用API。我考虑过使用Cognito身份池和基于属性的访问控制。

is a cool example,其中用户获得一个属性"department": "legal",然后被分配一个角色,该角色仅允许查询带有-legal后缀的存储桶,这要归功于${aws:PrincipalTag/department}魔术。

如果我的用户只访问一个存储桶,那将是一个解决方案。但是,在我的情况下,一个用户可能会被分配到几十个或数百个存储桶(在AWS文档的示例中考虑多个部门)。

我想对每个用户使用多个自定义属性:

  • bucket_1: true
  • bucket_2: false
  • bucket_3: false
  • ..等等

并创建允许您访问给定bucket_n的策略,当且仅当您具有属性bucket_n: true时。

如果我最多有50个存储桶(Cognito中的自定义属性的硬限制),则可以这样做。

在我的例子中,这个值稍高一些(几百)。我可以让用户访问200多个存储区,也可以只允许用户访问一个存储区。

是否有使用Cognito标识池和IAM策略实现我的目标的方法?

推荐答案

好的,我发现了一个可能对您中的某些人有用的解决办法(&Q;)。

首先,转到Cognito用户池并创建一个您选择的自定义属性,该属性将保存您的所有值。请记住,Cognito的属性值限制为2048个字符。

让我们将该属性称为attribute_groups。将所有值作为字符串放入其中,并使用您选择的分隔符。在我的例子中,具有custom:attribute_groups = "123o789"属性user1将意味着user1在逻辑上属于123789

映射这些属性in Cognito Identity Pools。按照主体的标记键:groups将从属性名称custom:attribute_groups中选择。

最后,设置用户池中经过身份验证的用户所采用的IAM策略,如下所示。在我的例子中,我希望允许组123列出s3://my_bucket/123456列出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/123aws s3 ls s3://my_bucket/789

遗憾的是,这仍然受到以下因素的严重限制:

  • IAM策略字符限制(10240)
  • Cognito自定义属性长度限制(2048)

使用这种细化的IAM策略,您最多可以拥有15-20个组和组。

您可以通过创建多个策略和多个Cognito User Pool组,将每个用户附加到每个组,然后使用ID token中的cognito:roles属性迭代这些组,并使用允许您设置CustomRoleArnGetCredentialForIdentity来承担这些角色。它可以工作(我已经检查过了),但真的很麻烦。

然而,有一个技巧可以将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个自定义属性,并相应地扩展您的策略。我认为这对于大多数传统用例应该足够了。

这篇关于Cognito身份池-使用"动态"属性进行基于属性的访问控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆