AWS Cognito 如何限制用户访问用户池内指定的App Client
实现Cognito按用户粒度管控App Client访问权限的方案
先说清楚问题根源:AWS Cognito用户池默认根本不内置「哪个用户能访问哪个App Client」的校验逻辑——只要是同一用户池下的App Client,池里所有用户都能走该Client的授权流程,默认就是全通的,这也是你现在碰到所有用户都能访问三个Web应用的核心原因。
具体落地步骤
- 第一步:在UserPool_1里新增一个自定义字符串类型的用户属性,命名为
custom_allowed_client_ids,把这个属性的修改权限设成「仅管理员可编辑」,别让用户自己改自己的权限 - 第二步:给三个用户的属性回填对应的允许访问范围,完全匹配你的需求规则:
- Mike的
custom_allowed_client_ids值,填WebClient_1、WebClient_2、WebClient_3对应的全部3个Client ID - Sarah的
custom_allowed_client_ids值,只填WebClient_3对应的Client ID - John的
custom_allowed_client_ids值,只填WebClient_2对应的Client ID
- Mike的
- 第三步:给UserPool_1绑定预认证(PreAuthentication)Lambda触发器——这个触发器的触发时机刚好在Cognito校验完用户密码、准备签发访问令牌之前,拦截位置完全符合需求。触发器只需要写最核心的判断逻辑就行:
- 从Lambda收到的事件里拿两个关键值:当前发起登录请求的App Client ID(就是事件结构里的
clientId字段)、当前尝试登录的用户的全量属性 - 把用户的
custom_allowed_client_ids属性值拆成列表,判断当前请求的clientId是不是在这个允许列表里 - 如果不在列表里,直接抛错返回
User not authorized,整个认证流程直接中断;如果在列表里就正常放行,走后面的token签发流程
- 从Lambda收到的事件里拿两个关键值:当前发起登录请求的App Client ID(就是事件结构里的
这些坑别踩
- 别折腾「给每个App Client单独建一个用户池」的笨办法:这种方式要跨好几个池同步用户数据,改密码、加用户、调权限都要操作好几遍,维护成本高到离谱,完全是绕远路
- 别指望靠App Client的「合法回调URL」配置实现拦截:那个配置只管OAuth流程的跳转地址合不合法,挡不住直接调Cognito公开接口的请求,更做不到按用户分权限,根本达不到你要的效果
实际效果
等Sarah下次试着通过WebClient_1点登录的时候,会直接被这个预认证Lambda拦下来,前端收到的就是你要的「User not authorized」提示,根本拿不到访问WebClient_1的合法令牌,从认证入口就把访问挡住了。
内容的提问来源于stack exchange,提问作者Eric Bergman
相关产品推荐
相关产品推荐

