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

Keycloak SSO会话闲置超时未触发,JHipster应用配置求助

Keycloak会话闲置超时未触发登出问题排查(JHipster+Spring Boot环境)

问题描述

我们的应用基于JHipster构建,技术栈包含Spring Boot、Keycloak和PostgreSQL数据库。已在Keycloak领域设置中将「SSO Session Idle」时间配置为1分钟,预期用户闲置1分钟及以上时Keycloak会发送登出事件,但实际无任何反应:Keycloak无相关日志,会话仍处于活跃状态,用户可正常调用其他REST API。

相关日志

登录Keycloak时观察到以下日志:

03:57:20,717 WARN  [org.keycloak.events] (default task-64) type=REFRESH_TOKEN_ERROR, realmId=google, clientId=youtube, userId=8299cea8-8ebf-45df-8685-b37445620255, ipAddress=10.198.140.148, error=invalid_token, grant_type=refresh_token, refresh_token_type=Offline, refresh_token_id=2b031b6d-5ff4-4967-a300-42b930dfc04b, client_auth_method=client-secret

解决方案:Spring Boot配置调整

要让JHipster应用接收Keycloak会话过期事件并实现自动登出,需在application.yaml或application_prod.yaml中添加以下关键配置:

1. 启用Keycloak会话校验

让应用定期同步Keycloak的会话状态,确保本地会话和Keycloak端保持一致:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: ${keycloak.auth-server-url}/realms/${keycloak.realm}
          jwk-set-uri: ${keycloak.auth-server-url}/realms/${keycloak.realm}/protocol/openid-connect/certs
      client:
        provider:
          keycloak:
            issuer-uri: ${keycloak.auth-server-url}/realms/${keycloak.realm}
        registration:
          keycloak:
            client-id: ${keycloak.client-id}
            client-secret: ${keycloak.client-secret}
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"
            scope: openid,profile,email

keycloak:
  auth-server-url: <你的Keycloak服务地址>
  realm: <你的领域名称>
  client-id: <你的客户端ID>
  client-secret: <你的客户端密钥>
  use-resource-role-mappings: true
  bearer-only: false
  # 开启Keycloak会话状态校验
  check-token-realm: true
  # 用JPA存储令牌,便于同步会话状态
  token-store: jpa

2. 同步本地会话超时时间

设置Spring Boot本地会话超时和Keycloak的SSO闲置时间一致,避免本地会话残留:

server:
  servlet:
    session:
      timeout: 1m
      tracking-modes: cookie

3. 主动处理Keycloak登出事件(可选)

如果需要主动监听Keycloak的登出事件,可以实现自定义登出处理器,确保应用端同步登出:

@Component
public class CustomKeycloakLogoutHandler implements LogoutHandler {

    private final OAuth2AuthorizedClientService authorizedClientService;

    public CustomKeycloakLogoutHandler(OAuth2AuthorizedClientService authorizedClientService) {
        this.authorizedClientService = authorizedClientService;
    }

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
        OAuth2AuthorizedClient client = authorizedClientService.loadAuthorizedClient(
                oauthToken.getAuthorizedClientRegistrationId(),
                oauthToken.getName());

        if (client != null) {
            String logoutUrl = client.getClientRegistration()
                    .getProviderDetails()
                    .getConfigurationMetadata()
                    .get("end_session_endpoint") + "?id_token_hint=" + client.getAccessToken().getTokenValue();

            try {
                response.sendRedirect(logoutUrl);
            } catch (IOException e) {
                throw new RuntimeException("跳转Keycloak登出端点失败", e);
            }
        }
    }
}

然后在安全配置类中注册该处理器:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private final CustomKeycloakLogoutHandler logoutHandler;

    public SecurityConfiguration(CustomKeycloakLogoutHandler logoutHandler) {
        this.logoutHandler = logoutHandler;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2Login()
                .and()
                .logout()
                .addLogoutHandler(logoutHandler)
                .logoutSuccessUrl("/");
    }
}

日志异常说明

日志中的REFRESH_TOKEN_ERROR是离线刷新令牌无效导致的,和当前会话闲置超时问题无关。如果应用使用了离线令牌,需检查Keycloak中离线令牌的有效期配置,避免影响正常令牌刷新流程。

Keycloak端额外检查

  • 确认Keycloak领域的「SSO Session Idle」设置已正确保存,未被客户端级别的Access Token Lifespan等参数覆盖
  • 检查Keycloak的「Session Idle」和「Session Max」时间配置,确保闲置超时规则生效
  • 确保Keycloak事件日志级别设置为WARN或更高,以便能捕获到会话过期相关日志

内容的提问来源于stack exchange,提问作者Raj Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:50:29