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组件发起的请求:框架会自动处理,无需额外配置。
- 对于自定义请求:
- 获取上述
CsrfToken的值。 - 在请求头中添加
X-Vaadin-CSRF-Token: [token值]。 - 如果是表单提交,也可以将Token放在名为
csrfToken的隐藏字段中。
- 获取上述
关键注意事项
- 不要同时启用Spring Security的CSRF和Vaadin的CSRF,两者机制不同,会导致冲突。
- 依赖
VaadinWebSecurity的默认配置处理Vaadin请求的权限和CSRF排除,不要手动覆盖核心规则。
内容的提问来源于stack exchange,提问作者IceMajor
相关产品推荐
相关产品推荐

