在角色分配的策略中不识别aws自定义属性



目标:通过cognito userpool + identitypool为一个用户分配一个自定义属性:tenantId访问他自己在S3中的桶文件夹:S3://[tenantId]/*

我配置:

  • 一个带有客户属性tenantId的用户池,并赋予应用客户端对该属性的读权限
  • 附加身份池
  • 创建一个角色,并将其附加到身份池

通过登录页面,我已经检索了一个有效的idToken,并给定该idToken,我执行以下代码(简化的示例,没有错误处理等):

const REGION            = '...';
const USERPOOLID        = '...';
const IDENTITYPOOLID    = '...';
const BUCKET            = '...';
const KEY               = '...';
const TEST_JWT_ID_TOKEN = 'xxx.yyy.zzz';
AWS               = require('aws-sdk');
AWS.config.region = REGION;
const cognitoIdentityObj = {
    IdentityPoolId: IDENTITYPOOLID,
    Logins        : {
        [`cognito-idp.${REGION}.amazonaws.com/${USERPOOLID}`]: TEST_JWT_ID_TOKEN
    },
};
AWS.config.credentials   = new AWS.CognitoIdentityCredentials(cognitoIdentityObj);
AWS.config.credentials.get(function (err) {
    if (!err) {
        const accessKeyId     = AWS.config.credentials.accessKeyId;
        const secretAccessKey = AWS.config.credentials.secretAccessKey;
        const sessionToken    = AWS.config.credentials.sessionToken;
        if (accessKeyId && secretAccessKey && sessionToken) {
            const AWS_S3 = new AWS.S3({accessKeyId, secretAccessKey, sessionToken});
            const params = {
                Bucket: BUCKET,
                Key   : KEY
            };
            AWS_S3.getObject(params, function (err, data) {
                if (err) {
                    // err is an Access Denied
                    console.error(err);
                } else {
                    console.log(data);
                }
            })
        }
    }
})

TEST_JWT_ID_TOKEN包含一个有效的ID Token,并且在登录时通过身份池将用户附加到一个角色。该角色具有以下定义的策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<BUCKET>/${cognito-identity.amazonaws.com:custom:tenantId}/*"
            ]
        }
    ]
}

然而,当我试图从该桶中读取时,我得到访问拒绝,在策略中添加资源行,如下所示:

arn:aws:s3:::<BUCKET>/* 

做到了这一点,所以我相当确定用户池、身份池、角色和策略的整个设置都在工作。然而,属性:${cognitatoidentity.amazonaws.com:custom:tenantId}似乎没有被识别/不评估或…

那么,您需要的是在IAM Authenticated Role策略上添加策略条件,并限制s3策略上的主体访问。查看Amazon S3可用的条件键操作、资源和条件键。在这种情况下,我使用前缀键,在另一种情况下,我将使用ExistingObjectTag。

我从来不知道"认知身份"这个词。在我的项目中,我使用的是"cognito-identity.amazonaws.com:sub"对于身份角色id reference和& cognita-identity.amazonaws.com:aud">

对于IAM Authenticated Role策略,我将语句写入如下:

"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "s3:ListBucket"
        ],
        "Condition": {
            "StringLike": {
                "s3:prefix": ["${cognito-identity.amazonaws.com:sub}"]
            }
        },
        "Resource": "arn:aws:s3:::<BUCKET_NAME>"
    },
    {
        "Effect": "Allow",
        "Action": [
            "s3:GetObject"
        ],
        "Resource": ["arn:aws:s3:::<BUCKET_NAME>/${cognito-identity.amazonaws.com:sub}/*"]
    }
]

在s3策略上,我将只限制已验证角色的主体访问:

"Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": <IAM_AUTH_ROLE_ARN>
        },
        "Action": "s3:ListBucket",
        "Resource": "arn:aws:s3:::<BUCKET_NAME>"
    },
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": <IAM_AUTH_ROLE_ARN>
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::<BUCKET_NAME>/*"
    }
]

官方文档Amazon S3:允许Amazon Cognito用户访问其bucket中的对象

这里有一篇很好的文章,解释了如何使用自定义认知属性来限制对桶前缀的访问。

https://www.chaosgears.com/post/enabling-amazon-cognito-identity-pools-and-aws-iam-to-perform-attribute-based-access-control

访问控制的属性可以映射到您的自定义认知属性,然后可以通过AWS IAM作为IAM策略变量${AWS:PrincipalTag/tenantId}调用。然后使用s3前缀挑战策略变量。因此,s3前缀由tenantId分隔(即-在s3存储桶中,每个租户都有单独的文件夹(前缀))。

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "s3:PutObject",
            "s3:GetObject",
            "s3:DeleteObject"
        ],
        "Resource": [
            "arn:aws:s3:::BUCKET-NAME/*"
        ],
        "Condition": {
            "ForAnyValue:StringEquals": {
                "aws:PrincipalTag/tenantId": "${s3:prefix}"
            }
        }
    }
]

}

最新更新