Spring Security OIDC+WebFlux每次请求调用Keycloak问题求助
解决WebFlux集成Keycloak后每次请求重复调用IDP的问题
排查方向与解决方案
1. 确认会话Cookie是否被正确携带
日志显示已找到SecurityContext,但仍重复调用Keycloak,首先要检查客户端请求是否携带了Spring Session的会话Cookie(默认名为SESSION)。如果客户端每次请求都没带这个Cookie,服务器会新建会话,导致每次都触发登录流程:
- 前端请求需确保携带Cookie(比如Axios设置
withCredentials: true,跨域场景下需配置CORS允许携带Cookie)。
2. 调整Security过滤器链配置顺序
确保securityContextRepository的配置在认证规则之前,让服务器优先从WebSession加载已有的安全上下文,避免重复触发OAuth2登录流程:
@Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ServerLogoutSuccessHandler handler) { http // 优先加载WebSession中的安全上下文 .securityContextRepository(new WebSessionServerSecurityContextRepository()) .authorizeExchange(exchanges -> exchanges .anyExchange().authenticated() ) .oauth2Login(withDefaults()) .logout(logout -> logout.logoutSuccessHandler(handler)); return http.build(); }
3. 配置会话超时与缓存
默认内存会话的超时时间较短,可延长会话有效期,同时确保会话仓库正确缓存会话:
@Bean public ReactiveSessionRepository reactiveSessionRepository() { ReactiveMapSessionRepository sessionRepo = new ReactiveMapSessionRepository(new ConcurrentHashMap<>()); // 设置会话超时为1小时,可根据业务调整 sessionRepo.setDefaultMaxInactiveInterval(Duration.ofHours(1)); return sessionRepo; }
4. 避免重复调用Keycloak用户信息端点
如果每次请求都触发Keycloak用户信息接口调用,可通过自定义ReactiveOAuth2UserService缓存用户信息,仅在登录时调用一次:
@Bean public ReactiveOAuth2UserService<OAuth2UserRequest, OAuth2User> cachedOAuth2UserService() { DefaultReactiveOAuth2UserService delegate = new DefaultReactiveOAuth2UserService(); // 缓存用户信息,后续请求直接复用 return request -> delegate.loadUser(request).cache(); }
5. 检查Keycloak客户端配置
确认Keycloak客户端的Access Type设置为confidential(Web应用需此类型),且Valid Redirect URIs、Web Origins配置正确,避免因客户端配置问题导致重复授权。
内容的提问来源于stack exchange,提问作者sashok_bg
相关产品推荐
相关产品推荐

