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

无状态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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:54:10