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

Vaadin请求CSRF Token获取失败及存在性验证问题

问题分析与解决办法

核心原因

你遇到的问题本质是Vaadin自身的CSRF机制和Spring Security的CSRF配置冲突:

  • 当你禁用Spring Security的CSRF后,Spring不会生成_csrf属性,所以通过VaadinRequest.getCurrent().getAttribute("_csrf")自然拿不到值。
  • Vaadin的CSRF Token是框架自动管理的,默认情况下,所有Vaadin发起的请求(比如组件交互、AJAX请求)都会自动带上这个Token,不需要手动干预。你尝试通过X-CSRF-TOKEN头获取,是混淆了Spring Security的CSRF Token和Vaadin自身的Token。

解决步骤

1. 调整Spring Security配置,适配Vaadin的CSRF机制

不需要手动禁用Spring Security的CSRF,而是让Spring Security忽略Vaadin的内部请求,同时保留Vaadin自身的CSRF防护。修改你的SecurityVaadinConfig:

@Configuration
@EnableWebSecurity
public class SecurityVaadinConfig extends VaadinWebSecurity {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 先调用父类配置,VaadinWebSecurity会自动处理CSRF的排除规则
        super.configure(http);
        // 设置登录视图
        setLoginView(http, LoginView.class);
        // 配置权限规则
        http.authorizeHttpRequests(auth -> auth
                .requestMatchers(AntPathRequestMatcher.antMatcher("/images/**"),
                                AntPathRequestMatcher.antMatcher("/styles/**"))
                .permitAll()
                .anyRequest().authenticated());
    }

    @Override
    protected void configure(WebSecurity web) throws Exception {
        // 让Spring Security忽略Vaadin的静态资源和内部请求
        web.ignoring().requestMatchers(
                AntPathRequestMatcher.antMatcher("/VAADIN/**"),
                AntPathRequestMatcher.antMatcher("/frontend/**"),
                AntPathRequestMatcher.antMatcher("/webjars/**"),
                AntPathRequestMatcher.antMatcher("/frontend-es5/**"),
                AntPathRequestMatcher.antMatcher("/frontend-es6/**"));
        super.configure(web);
    }
}

注意:VaadinWebSecurity父类已经内置了适配Vaadin的CSRF处理逻辑,会自动排除Vaadin的内部请求,避免冲突。不要手动调用http.csrf().disable(),否则会破坏Vaadin的CSRF防护。

2. 如何获取Vaadin自身的CSRF Token(自定义请求场景)

如果需要在自定义AJAX请求中手动携带Vaadin的CSRF Token,可以通过以下方式获取:

// 在Vaadin视图类中获取
CsrfToken token = VaadinSession.getCurrent().getAttribute(CsrfToken.class);
String csrfTokenValue = token.getToken();
// 自定义请求时,需要将Token放在`X-Vaadin-CSRF-Token`头中

Vaadin的CSRF Token默认通过X-Vaadin-CSRF-Token头传递,而非Spring Security常用的X-CSRF-TOKEN,这也是你之前拿不到值的原因之一。

3. 确保所有请求自动携带Token

  • 对于Vaadin组件发起的请求:框架会自动处理,无需额外配置。
  • 对于自定义请求:
    1. 获取上述CsrfToken的值。
    2. 在请求头中添加X-Vaadin-CSRF-Token: [token值]。
    3. 如果是表单提交,也可以将Token放在名为csrfToken的隐藏字段中。

关键注意事项

  • 不要同时启用Spring Security的CSRF和Vaadin的CSRF,两者机制不同,会导致冲突。
  • 依赖VaadinWebSecurity的默认配置处理Vaadin请求的权限和CSRF排除,不要手动覆盖核心规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:10:21