下面介绍如何通过Cognito Identity Pool实现细粒度的访问控制。

AWS Cognito
AWS Cognito系列教程:
- React+AWS Cognito教程一:创建User Pool并实现用户注册及用户登录
- React+AWS Cognito教程二:Cognito中的Session及注销登录
- React+AWS Cognito教程三:在Cognito中更改密码
- React+AWS Cognito教程四:使用Cognito中的自定义属性
- React+AWS Cognito教程五:通过AWS Cognito UserPool保护APIGateway
- React+AWS Cognito教程六:Cognito内置的OAuth支持-使用Google登录
- Cognito中的细粒度用户访问授权
何时需要使用AWS Cognito Identity Pools
- 针对认证/非认证用户进行不同的AWS资源访问控制
- 在使用federated identities(比如OAuth)登录后,访问AWS资源
- 临时授权给APP/用户访问AWS资源
- 细粒度权限控制
在OAuth登录后如何获取临时的credentials
基本步骤是这样的:
- APP发起登录请求
- ISP Provider认证并返回JWT Token
- APP向Cognito Identity Pool发起请求,获取AWS Credentials(GetCredentialsForIdentity)
- Identity Pool(根据Assumed Role)向APP返回临时Credentials(包括accessKey, secret, sessionToken)
- APP向AWS资源(S3, Lambda, DynamoDB)等发起请求,同时需提供Access key ID, Secret access key, Session ID
在Identity Pool中的访问控制选项
- Guess access:设定访客访问权限
- Authenticated access(已认证用户):对于所有认证用户的授权一样
- Role based access control (RBAC, 基于角色的访问控制):访问控制取决于用户的角色。
- 使用attributes来进行访问控制:从用户profile中的属性在运行时临时决定其访问权限。
对于基于角色的访问控制,这里又有两种方式来决定用户角色:
- 根据token来决定role(User Pool Group),这里需要在User Pool中将用户添加到一个group中,同时授权该group对相应资源的访问。
- 或者根据预定义规则来决定role。这里需要根据返回token中的attribute来角色来确定用户的role并将对应的IAM role赋予该用户。
基于角色的访问控制(比如在OAuth中)
文档:https://docs.aws.amazon.com/cognito/latest/developerguide/role-based-access-control.html
当APP发起登录请求时,IDP对其身份进行验证后返回JWT token,如果实现已经将该用户添加到一个group并对该group赋予相应权限的话,这个操作就很简单了。只要用户登录成功,该用户就自动具备他所属group中赋予的权限。
比如:创建一个Admin group并赋予其足够的权限(通过IAM Role),并将相关用户(手工)添加到该group中:

AWS Cognito教程
登录成功后,返回的JWT token中包含:
json
{
...
"cognito:groups": ["Admin"],
"cognito:preferred_role":"arn:aws:iam::XXXX:role/Admin"
...
"cognito:roles":[
"arn:aws:iam::XXXX:role/Admin"
]
}
在用户登录成功后,有三个选项:
- Use default role
- Choose role with rules
- Choose role from token
使用默认的role
这种方式最为简单,只要将用户加入一个group,并将该group和IAM Role关联,用户登录后就会自动被赋予对应的IAM role。
根据规则来选择role
通过这种方式,可以定义自己的规则(在Identity Pool中可以看到下面选项),比如:
当用户属性中的custom:tier equals ‘premium’时,赋予’premiumRole’
当用户属性中的custom:admin equals ‘true’时,赋予’AdminRole’
attributes for access control
但有些更为复杂的应用场景可能用Role Based Access Control还不能应付。比如:
- 用户拥有非常多的资源,比如上千个AWS resources,同时还有很多不同的group,这时对资源的访问控制很难用roles来定义
- 用户需要一个能够动态授权并易于扩展的授权机制
- 基于资源tags及用户属性进行授权
- …
通过这种方式,可以通过Identity Provider提供的属性来动态决定用户的权限。