You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keycloak中设置用户或组级别的会话闲置超时

解决Keycloak组级会话闲置超时覆盖域级配置的方案

针对Keycloak 20.0.1版本,无法修改核心代码的前提下,实现组级属性覆盖域级SSO会话闲置超时,以下是几种可行方案:

方案1:自定义SPI事件监听器(推荐,服务端可靠实现)

Keycloak支持通过SPI扩展功能,无需修改核心代码,仅需编写并部署自定义事件监听器,在会话生命周期中动态调整超时时间:

实现步骤

  1. 编写自定义EventListenerProvider和对应的EventListenerProviderFactory,监听用户会话的创建与更新事件:

    • 在会话创建(onSessionCreated)或更新(onSessionUpdated)时,获取当前用户的所有组
    • 遍历组属性,提取预设的会话闲置超时值(比如属性名设为session-idle-timeout,单位分钟)
    • 取所有组中最小的超时值(若用户属于多组),调用session.setMaxIdleTime()覆盖会话的闲置超时配置
  2. 将编译打包后的jar文件放入Keycloak的providers目录,执行kc.sh build(Windows下为kc.bat build)重新构建,重启Keycloak

  3. 在Keycloak控制台的目标域中,进入Events > Config,启用自定义的事件监听器

核心代码示例

@Override
public void onSessionCreated(AdminEvent event, UserSessionModel session) {
    if (session.getUser() == null) return;
    
    long effectiveTimeout = -1;
    List<GroupModel> userGroups = session.getUser().getGroupsStream().collect(Collectors.toList());
    
    for (GroupModel group : userGroups) {
        String timeoutAttr = group.getAttribute("session-idle-timeout");
        if (timeoutAttr == null) continue;
        
        try {
            long timeoutMs = Long.parseLong(timeoutAttr) * 60 * 1000; // 转换为毫秒
            if (effectiveTimeout == -1 || timeoutMs < effectiveTimeout) {
                effectiveTimeout = timeoutMs;
            }
        } catch (NumberFormatException ignored) {
            // 忽略格式错误的属性值
        }
    }
    
    if (effectiveTimeout != -1) {
        session.setMaxIdleTime(effectiveTimeout);
    }
}

@Override
public void onSessionUpdated(AdminEvent event, UserSessionModel session) {
    // 会话更新时重新校验组属性,支持动态修改组配置后即时生效
    onSessionCreated(event, session);
}

方案2:前端主动闲置检测与登出

若不想部署服务端扩展,可在前端实现闲置检测逻辑:

  • 监听用户鼠标、键盘等交互事件,记录最后活动时间
  • 登录时通过Keycloak的用户属性映射器,将组的超时属性注入ID Token或UserInfo响应中
  • 当超出组级闲置时间后,调用Keycloak JS SDK的logout()方法主动触发登出

注意:该方案依赖前端JS,存在用户禁用JS后的安全风险,仅作为备选方案。

方案3:客户端级超时映射(仅适用于组-客户端一一对应场景)

如果用户组与客户端存在明确的一一对应关系,可:

  • 给每个客户端单独配置会话闲置超时
  • 通过Keycloak的组-客户端角色映射,限制特定组用户仅能访问对应客户端
  • 以此间接实现组级别的超时控制

关键提示

不要尝试修改会话的lastAccessTime属性,Keycloak的会话过期逻辑是基于lastAccessTime + maxIdleTime计算的,修改lastAccessTime到过去无法从根本上覆盖域级超时配置,正确的方式是通过setMaxIdleTime()直接调整会话的闲置超时阈值。

内容的提问来源于stack exchange,提问作者Shubham Khankale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:31:38