使用thymeleaf+spring security处理csrf时遇到Cannot create a session after the response has been committed

探讨SpringSecurity中CSRF机制与Thymeleaf页面渲染的交互问题,特别是在懒加载session与页面缓冲提交冲突时的解决方案。文章提供了一种在head标签中设置CSRF的保险方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录


spring security中默认csrf是懒加载的,只有在第一次使用_csrf时才会创建session

而thymeleaf页面的缓冲区满后,response会在模板渲染完毕前被提交,所以response已提交时,若在剩余的模板代码中使用了_csrf并且之前还没创建过session,就会报错

还是用head的方式保险

<head>
	<meta name="_csrf" th:content="${_csrf.token}"/>
	<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>
var header = $("meta[name='_csrf_header']").attr("content");
var token = $("meta[name='_csrf']").attr("content");
 
$.ajax({
    url: '/test',
    type: 'POST',
    beforeSend: function(xhr){
        xhr.setRequestHeader(header, token);
    },
    success: function(data) {
        console.log(data);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr.status + ": " + thrownError);
    }
});

参考:
https://www.cnblogs.com/ismallboy/p/6785328.html
https://blog.youkuaiyun.com/starrrr2/article/details/50074445

### Spring Boot 3、ThymeleafSpring Security 的应用开发教程 #### 一、项目初始化 为了使用 Spring Boot 3 开发基于 ThymeleafSpring Security 的应用程序,首先需要创建一个新的 Maven 或 Gradle 项目。以下是具体的依赖配置: 在 `pom.xml` 文件中添加以下依赖项来支持 ThymeleafSpring Security 功能: ```xml <dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Thymeleaf Template Engine --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> ``` 这些依赖分别用于启用 Spring MVC[^1]、模板引擎 Thymeleaf[^1] 和安全框架 Spring Security[^4]。 --- #### 二、Spring Security 配置 在 Spring Boot 中集成 Spring Security 可以为应用程序提供身份验证和授权功能。可以通过编写一个自定义的安全配置类实现这一点。 创建名为 `MySecurityConfig.java` 的配置类并继承 `WebSecurityConfigurerAdapter`(注意:在 Spring Security 5.7.x 后已废弃此适配器,推荐直接注入 Bean)。以下是示例代码: ```java import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; public class MySecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((requests) -> requests .requestMatchers("/", "/home").permitAll() .anyRequest().authenticated()) .formLogin((form) -> form .loginPage("/login") .defaultSuccessUrl("/dashboard", true)) .logout((logout) -> logout.logoutUrl("/logout")) .csrf().disable(); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 这段代码实现了基本的身份验证逻辑,包括登录页面指定、成功重定向以及 CSRF 攻击防护关闭等功能[^4]。 --- #### 三、Thymeleaf 页面设计 Thymeleaf 是一种现代服务器端 Java 模板引擎,能够很好地与 HTML 结合工作。可以在项目的 `src/main/resources/templates/` 路径下创建 `.html` 文件作为视图层。 例如,创建一个简单的登录页面 `login.html` 如下所示: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Login Page</title> </head> <body> <h1>Login to your account</h1> <form th:action="@{/login}" method="post"> <label for="username">Username:</label> <input type="text" id="username" name="username"/> <br/> <label for="password">Password:</label> <input type="password" id="password" name="password"/> <br/> <button type="submit">Log In</button> </form> </body> </html> ``` 这个表单会提交至 `/login` URL 地址,并由 Spring Security 处理认证请求[^2]。 --- #### 四、控制器设置 最后一步是为前端页面绑定对应的后端处理方法。可以创建一个基础的控制器类完成这一目标。 示例代码如下: ```java import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HomeController { @GetMapping("/") public String home() { return "index"; // 映射到 templates/index.html } @GetMapping("/login") public String login() { return "login"; // 映射到 templates/login.html } @GetMapping("/dashboard") public String dashboard() { return "dashboard"; // 用户登录后的主页映射 } } ``` 以上代码展示了如何通过注解的方式将 HTTP 请求路由到特定的方法上。 --- #### 总结 本教程介绍了如何利用 Spring Boot 3 构建集成了 ThymeleafSpring Security 的简单 Web 应用程序。涵盖了从项目搭建到核心组件配置的过程,帮助开发者快速入门此类技术栈的应用开发。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值