如何阻止 Spring Boot 添加会话 cookie?

Posted

技术标签:

【中文标题】如何阻止 Spring Boot 添加会话 cookie?【英文标题】:How to stop Spring Boot from adding session cookies? 【发布时间】:2020-06-02 23:21:33 【问题描述】:

我有一个 Spring Boot Web 应用程序,我正在尝试使其无状态。在我的 WebSecurityConfigurerAdapter 我已经设置了

    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

但应用程序(使用 Thymeleaf 模板)通过在文件名后附加“;jsessionid=<some_session_id>”不断重写图像和脚本的 URL。除了给我一个我不想要的cookie之外,它还有一个恼人的副作用是Spring Security会阻止请求,因为它在URL中有一个分号!

Thymeleaf says this is the intended and desired behavior 说这不是他们的错:Thymeleaf 只是要求“Servlet API”重写 URL,我们应该“在 Tomcat 上下文级别配置应用程序”来解决问题。

那么,我该怎么做呢?我有一个用于授权的自定义 JWT cookie,所以我根本不需要或不需要会话 cookie,当然不是在重写的 URL 中。

【问题讨论】:

最后我决定继续使用会话 ID,但在 this answer to "How can I use Spring Security without sessions" 之后取消了它让用户在基于 JWT 的身份验证之外保持登录的能力 【参考方案1】:

jsessionid 行为,与 STATELESS 无关。

最初,servlet 容器不知道客户端(浏览器)是否支持 cookie。

因此,对页面的第一个请求(通常是 HTTP GET):

    servlet 容器会将 ;jsessionid=... 附加到所有 URL。 servlet 容器将(尝试)使用jsessionid 设置一个cookie。

当点击链接或提交公式(HTTP GET/POST)时,浏览器会将 cookie 发送回服务器,如果且仅当浏览器确实接受了首先设置的 cookie。 现在,servlet 容器可以识别 jsessionid 是来自 cookie(通过 HTTP 请求标头传输)还是来自 URL。

如果 jsessionid 源自 cookie,则 servlet 容器将停止将 ;jsessionid=... 附加到 URL。 如果jsessionid 来自您单击的 URL,它将继续将;jsessionid= 附加到所有 URL。

这与 STATELESS 或SessionCreationPolicy 的任何其他配置无关。

查看SessionCreationPolicy 的 Spring Security 文档:

/** Always create an @link HttpSession */
ALWAYS,
/**
 * Spring Security will never create an @link HttpSession, but will use the
 * @link HttpSession if it already exists
 */
NEVER,
/** Spring Security will only create an @link HttpSession if required */
IF_REQUIRED,
/**
 * Spring Security will never create an @link HttpSession and it will never use it
 * to obtain the @link SecurityContext
 */
STATELESS

更新:

要通过 URL 禁用跟踪模式,请设置以下属性:

server.servlet.session.tracking-modes: COOKIE

见:https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html

【讨论】:

那么,有什么办法可以禁用这种行为?我唯一的解决方案就是放弃 STATELESS 并允许 cookie(但忽略它)。 检查拼写。是server.servlet... 还是servlet.servlet...

以上是关于如何阻止 Spring Boot 添加会话 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

如何访问@JmsListener使用的Spring Boot中的活动JMS连接/会话

从 https 切换到 http 时登录后 spring-boot 用户会话未添加到上下文中

Spring boot + spring security - 如何阻止应用层上的CORS请求?

如何使用 Spring Security 管理 Spring Boot 中的会话?

spring-boot redis:如何使用户的所有会话无效?

Spring Boot:迭代和评估所有(活动)会话