Spring Boot中大型Thymeleaf模板带CSRF令牌触发异常的解决方案咨询
可行解决方案
- 调整服务器响应缓冲区大小
这是成本最低的方案,直接将Catalina的默认输出缓冲区调整到大于你的最大模板体积即可。
配置方式有两种:- 全局配置:修改Tomcat
conf/server.xml中的Connector节点,添加bufferSize属性,单位为字节,例如设置为64kb:<Connector port="8080" protocol="HTTP/1.1" bufferSize="65536" .../> - 单接口精细控制:在对应控制器的处理逻辑中,调用
response.setBufferSize(65536)单独调整该请求的缓冲区大小
- 全局配置:修改Tomcat
- 提前触发会话创建
在模板渲染逻辑执行前就主动完成会话初始化,避免后续需要CSRF时才创建会话。
操作方式:在对应控制器方法中主动调用request.getSession(true);如果是全局场景,可以新增一个过滤器,在请求进入视图渲染层之前,判断该请求需要返回HTML页面且用到CSRF校验时,提前触发会话创建。 - 调整模板渲染顺序,提前加载CSRF依赖
将CSRF相关的逻辑移到模板最开头的位置,在缓冲区第一次被填满flush之前就完成CSRF令牌的获取,此时会话已经创建,后续flush不会再触发报错。
例如可以在<head>标签中就预先输出CSRF的参数和头为全局变量:
后续页面的表单提交直接使用该全局变量即可,不需要依赖th:action自动生成令牌。<script> const CSRF_PARAM = /*[[${_csrf.parameterName}]]*/''; const CSRF_TOKEN = /*[[${_csrf.token}]]*/''; </script> - 按需禁用对应页面的CSRF保护(不推荐,仅适用于无敏感操作的场景)
如果该页面的表单没有敏感操作、不会修改用户数据,可以在安全框架配置中排除该路径的CSRF校验,此时渲染模板时不会再获取CSRF令牌,自然也不会触发会话创建的逻辑。
内容的提问来源于stack exchange,提问作者Yimo
相关产品推荐
相关产品推荐

