如何在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
相关产品推荐
相关产品推荐

