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

如何在Thymeleaf项目中实现Spring Security CSRF防护?

Spring Boot + Thymeleaf 配置CSRF防护指南

问题背景

开发基于Spring Boot和Thymeleaf的项目时,需启用CSRF防护,以下是具体配置步骤:


一、依赖配置

确保项目引入Spring Security和Thymeleaf的starter依赖:

Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Gradle

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

二、Spring Security启用CSRF防护

Spring Security默认已启用CSRF防护,可在安全配置类中显式验证或调整规则:

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf() // 显式声明启用CSRF(默认已开启,此步可省略,仅作验证)
            .and()
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login").permitAll()
            .and()
            .logout().permitAll();

        return http.build();
    }
}

注:仅在特定场景(如纯API服务)建议禁用CSRF,使用.csrf().disable(),生产环境不推荐此操作。


三、Thymeleaf表单中包含CSRF令牌

Thymeleaf与Spring Security集成后,有两种方式注入CSRF令牌:

方式1:自动注入(推荐)

使用Thymeleaf的<form>标签并指定th:action属性,框架会自动生成包含CSRF令牌的隐藏域:

<form th:action="@{/submit}" method="post">
    <label for="name">名称:</label>
    <input type="text" id="name" name="name">
    <button type="submit">提交</button>
</form>

方式2:手动添加

若需手动控制,可直接添加隐藏域:

<form method="post" action="/submit">
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
    <label for="name">名称:</label>
    <input type="text" id="name" name="name">
    <button type="submit">提交</button>
</form>

四、AJAX请求中处理CSRF令牌

AJAX请求需在请求头中携带CSRF令牌,步骤如下:

1. 在HTML头部添加meta标签

在页面<head>中注入CSRF令牌及对应请求头名称:

<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>

2. 在AJAX请求中携带令牌

以fetch为例:

const csrfToken = document.querySelector('meta[name="_csrf"]').content;
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content;

fetch('/submit', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        [csrfHeader]: csrfToken
    },
    body: JSON.stringify({ name: '测试' })
});

若使用jQuery ajax:

const csrfToken = $('meta[name="_csrf"]').attr('content');
const csrfHeader = $('meta[name="_csrf_header"]').attr('content');

$.ajax({
    url: '/submit',
    type: 'POST',
    contentType: 'application/json',
    headers: {
        [csrfHeader]: csrfToken
    },
    data: JSON.stringify({ name: '测试' })
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:50:20