无状态Vaadin Fusion 22 OAuth2项目如何实现正确登出?
Vaadin Fusion无状态模式+Keycloak登出不生效解决方案
问题根因
- Spring Security默认登出逻辑未主动清除Vaadin无状态认证生成的JWT Cookie,残留的有效Cookie会触发自动重新认证
- 前端登出逻辑执行顺序错误,提前清理本地状态但未等后端和OIDC侧登出完成
- 部分场景下Keycloak客户端登出重定向地址未配置,导致OIDC侧登出失败
修复步骤
1. 调整Spring Security登出配置
在原有logout配置块中新增Cookie清理、认证信息清除逻辑,修改后代码如下:
@Override protected void configure(HttpSecurity http) throws Exception { // 设置默认安全策略,允许Vaadin内部请求,拒绝其余所有请求 super.configure(http); http.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); http // 启用OAuth2登录 .oauth2Login(oauth2Login -> oauth2Login.clientRegistrationRepository(clientRegistrationRepository) .userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint // 使用自定义权限映射器,将身份提供商的角色写入身份验证令牌 .userAuthoritiesMapper(authoritiesMapper)) // 使用适配Vaadin的身份验证成功处理器 .successHandler(new VaadinSavedRequestAwareAuthenticationSuccessHandler())) // 配置登出 .logout(logout -> logout .logoutSuccessHandler(logoutSuccessHandler()) .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")) // 新增配置开始 .clearAuthentication(true) .invalidateHttpSession(true) // 此处Cookie名需和Vaadin无状态认证生成的Cookie名一致,默认是vaadin.auth .deleteCookies("vaadin.auth", "JSESSIONID") // 新增配置结束 ); setStatelessAuthentication(http, new SecretKeySpec(Base64.getDecoder().decode(authSecret), JwsAlgorithms.HS256), "com.my.app"); } private OidcClientInitiatedLogoutSuccessHandler logoutSuccessHandler() { OidcClientInitiatedLogoutSuccessHandler logoutSuccessHandler = new OidcClientInitiatedLogoutSuccessHandler( clientRegistrationRepository); logoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}/"); return logoutSuccessHandler; }
2. 调整前端登出执行顺序
调整操作顺序,优先完成后端登出调用再清理前端本地状态,修改后代码如下:
export async function logout() { // 先调用后端登出实现,等待处理完成 await logoutImpl(); // 再清理前端会话状态和用户信息 setSessionExpired(); appStore.clearUserInfo(); // 最后跳转触发OIDC侧登出流程 location.href = '/logout'; }
3. 检查Keycloak客户端配置
登录Keycloak管理后台,找到对应客户端,确认以下配置:
- 「有效重定向URI」已添加应用根地址(如
http://localhost:8080/*) - 「有效登出重定向URI」已添加应用根地址(如
http://localhost:8080/*) - 「Web源」已添加应用地址(如
http://localhost:8080)
完成以上修改后即可正常完成全链路登出,点击登出后会先清理本地Cookie和认证信息,再跳转Keycloak完成账号登出,最后返回应用首页处于未登录状态。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

