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

Keycloak+Spring Security OIDC:SSO会话超时后无法重定向至登录页

问题描述

我有一个配置为Spring Security OAuth2 Client的Spring Boot应用,使用Keycloak作为OIDC提供商,后端同时提供编译后的Angular前端应用。Angular应用每秒向后端REST API发起请求。

用户在浏览器打开localhost:4881时,会被重定向到Keycloak登录页,登录成功后返回该地址渲染Angular应用。

用户登录后,Keycloak中会创建两个会话:Regular SSO和Offline。Regular SSO会话会按SSO空闲超时设置被清除,但Offline会话会在Keycloak中保留更久才被清除。

当前问题是:SSO会话触发空闲/最大超时后,UI无法自动重定向到Keycloak登录页。我认为Keycloak应该将超时事件通知OAuth2客户端,客户端需要将后续所有请求对应的UI重定向至登录页。

我已完成的配置:

  • 在Realm级别设置了SSO Session Idle、SSO Session Max和Offline Session Settings
  • 配置了客户端的Admin URL

我创建了同配置的示例应用,包含:

  • backend:配置为OAuth2 Client的Spring Boot应用,提供/api/currentTime接口返回当前时间
  • frontend:每秒调用后端接口获取时间的Angular应用
  • realm:配置文件路径为keycloak-oauth2-client-ui\backend\src\main\resources\demo-realm.json
  • 测试账号密码:demo/demo

解决方案

1. 后端配置:处理OAuth2会话失效异常

Spring Security OAuth2 Client不会主动检测Keycloak的SSO会话超时,需配置异常处理器,在请求因令牌失效/会话过期返回401时,触发重定向或返回明确状态码。

配置Spring Security异常处理

在Spring Security配置类中添加认证异常处理逻辑:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/**").authenticated()
                .anyRequest().permitAll()
            )
            .oauth2Login(Customizer.withDefaults())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .exceptionHandling(ex -> ex
                .authenticationEntryPoint((request, response, authException) -> {
                    // 识别OAuth2认证异常,重定向到Keycloak登录触发路径
                    if (authException instanceof OAuth2AuthorizationException) {
                        response.sendRedirect("/oauth2/authorization/keycloak");
                    } else {
                        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
                    }
                })
            );
        return http.build();
    }
}

2. 前端配置:捕获401状态触发重定向

Angular应用需通过HTTP拦截器捕获后端返回的401状态码,主动跳转到后端登录触发路径,由后端完成Keycloak重定向。

创建Angular HTTP拦截器

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401) {
          // 跳转到后端登录触发地址,触发Keycloak重定向
          window.location.href = '/oauth2/authorization/keycloak';
        }
        return throwError(() => error);
      })
    );
  }
}

注册拦截器到AppModule

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
  ]
})
export class AppModule { }

3. Keycloak端补充配置

  • 开启客户端的Front Channel Logout选项:当SSO会话超时或注销时,Keycloak会通过前端iframe通知客户端清除会话,触发重定向逻辑。
  • 检查SSO会话Cookie配置:确保KEYCLOAK_SESSION的HttpOnly、SameSite参数设置正确,保证前端能正确感知会话状态变化。

4. 处理Offline会话的影响

Offline会话用于长期授权,但SSO会话超时后,浏览器端的SSO会话已失效,需强制用户重新登录建立新的SSO会话,避免依赖Offline会话绕过登录流程。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:17:32