【发布时间】:2021-12-28 11:25:56
【问题描述】:
我将 SpringBoot、SpringSecurity 用于我的应用程序并使用 FreeMarker 来呈现视图(用于 spring-security 和 freemarker 的启动器)。
在使用 CSRF 令牌渲染更大的视图时遇到异常。这些视图超出了响应缓冲区大小,并且响应的第一部分在整个视图完全呈现之前已经提交。如果应该呈现一个 CSRF 令牌,我会遇到以下异常:
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:3049)
at org.apache.catalina.connector.Request.getSession(Request.java:2493)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:908)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:920)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:253)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:253)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:253)
at org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.saveToken(HttpSessionCsrfTokenRepository.java:58)
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.saveTokenIfNecessary(LazyCsrfTokenRepository.java:168)
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.getToken(LazyCsrfTokenRepository.java:125)
在过滤器中使用response.setBufferSize(..) 以编程方式设置更大的缓冲区似乎可以解决这个问题,但感觉不是一个好的解决方案。我不想为每个请求增加缓冲区,也不想跟踪哪些端点呈现视图并仅为它们增加缓冲区。此外,如果视图变大,当前的缓冲区大小可能会再次变得太小。
那么有没有更好的解决方案,例如在开始写入响应的作者之前渲染整个视图(没有发现如何实现这一点)?或者是否有一些弹簧安全配置允许在响应提交后获取令牌。或者我应该在控制器方法中急切地获取 CSRF 令牌并将它们传递给模型,以便 FreeMarker 能够独立于会话呈现视图?
【问题讨论】:
标签: spring-boot spring-security freemarker