如何在Keycloak中检测用户首次登录并添加first_login Token声明字段
实现Keycloak首次登录检测并在Token中添加
first_login声明 以下是几种可行的实现方案:
方案1:使用自定义Script Mapper(推荐,无需编译代码)
Keycloak支持通过Script Mapper编写Groovy脚本动态生成Token声明,步骤如下:
- 登录Keycloak管理控制台,进入目标客户端的Mappers页面
- 点击「Create」,选择
Script Mapper类型 - 配置参数:
- Name: 自定义名称(比如
first_login mapper) - Token Claim Name:
first_login - Claim JSON Type:
boolean - Script: 输入以下脚本
def user = user as org.keycloak.models.UserModel // 判断是否首次登录:lastLogin未设置(0或null)且未标记过已完成首次登录 def isFirstLogin = (user.lastLogin == null || user.lastLogin == 0L) && !user.getFirstAttribute("first_login_completed") if (isFirstLogin) { // 标记用户已完成首次登录,避免后续登录重复返回true user.setSingleAttribute("first_login_completed", "true") return true } return false
- Name: 自定义名称(比如
- 保存后,用户首次登录时,Token中就会包含
"first_login": true的声明;后续登录则返回false
方案2:自定义Authenticator(适合复杂场景)
如果需要更灵活的逻辑控制,可以开发自定义Authenticator:
- 创建Java项目,依赖Keycloak的
keycloak-core和keycloak-server-spi库 - 实现
Authenticator接口,在authenticate方法中检测首次登录:@Override public void authenticate(AuthenticationFlowContext context) { UserModel user = context.getUser(); boolean isFirstLogin = user.getLastLogin() == null || user.getLastLogin() == 0L; // 将状态存入AuthenticationSession的notes中 context.getAuthenticationSession().setAuthNote("first_login", String.valueOf(isFirstLogin)); // 可选:标记用户已完成首次登录 if (isFirstLogin) { user.setSingleAttribute("first_login_completed", "true"); context.getSession().users().updateUser(context.getRealm(), user); } // 继续执行认证流程 context.success(); } - 实现对应的
AuthenticatorFactory,打包成JAR后放到Keycloak的providers目录 - 重启Keycloak,在目标Realm的Authentication > Flows中,将自定义Authenticator添加到认证流程中
- 再创建一个自定义Token Mapper,读取AuthenticationSession中的
first_login值并添加到Token声明
方案3:利用用户属性+事件监听器
通过Keycloak的事件监听机制实现:
- 给用户添加默认属性
first_login_completed,值设为false - 创建一个事件监听器,监听
LOGIN事件:- 当触发登录事件时,检查用户的
first_login_completed属性 - 如果为
false,则在Token中注入first_login: true,并将属性更新为true
- 当触发登录事件时,检查用户的
- 配置客户端的映射器,将动态生成的
first_login字段添加到Token中
注意:此方案需要编写事件监听器代码并部署,复杂度高于Script Mapper方案。
内容的提问来源于stack exchange,提问作者UIC
相关产品推荐
相关产品推荐

