在身份验证期间使用 JWT 令牌反序列化 cookie 无法正确反序列化
Posted
技术标签:
【中文标题】在身份验证期间使用 JWT 令牌反序列化 cookie 无法正确反序列化【英文标题】:Deserializing cookie with JWT token during authentication fails to deserialize properly 【发布时间】:2021-04-05 08:54:37 【问题描述】:我在使用 Spring Security 为我的无状态应用程序反序列化 cookie 时遇到问题。
调用https://localhost:8080/login
并成功验证会生成一个包含 JWT 令牌和其他一些字段的 cookie,特别是 Secure
、HttpOnly
、SameSite=None
。例如,它看起来像下面这样(令牌仅在本地有效,已过期且不包含有用信息,随意窃取):
token=eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOiI2NzA1ZTk1YS1hOTgzLTRiMDItYmVjOC01ZGFkNDM0MzY0NzAiLCJleHAiOjE2MDkxNzA0Nzd9.9OF_iDuxlZ9Xk9v_YJJTDY0LCQ21mZENnKRafhYKv63KXZ3tkHzSZt0Ngskxp9-yaa10AEY5p1j44cGQ9KY-DQ; Max-Age=1800; Path=/; Secure; HttpOnly; SameSite=none; Domain=localhost
我已使用自签名证书和 .jks 文件将 https 添加到我的 localhost 调用以测试身份验证流程。我还测试了这个 cookie 实际上在 Insomnia/Postman 中设置正确。
我的 Spring Security 配置现在要求每个请求都存在一个带有有效令牌的 cookie。这工作正常。但是,当我尝试要求令牌在请求中具有与设置令牌时相同的字段时,我遇到了一个问题:
require(cookieContainingToken.isHttpOnly
&& cookieContainingToken.secure
&& cookieContainingToken.name == "token")
使用调试器,我可以看到 cookie 存在并包含正确的令牌,但不再是 httpOnly 且不安全。路径为空,域为空,maxAge 为-1。此外,Spring 使用的 javax.servlet.http.Cookie
类似乎没有 sameSite 属性。显然,cookie 的反序列化并没有完全奏效。
有没有办法使传入请求的 cookie 反序列化正常工作?还是我应该简单地忽略传入请求的这些属性并仅验证令牌?
【问题讨论】:
【参考方案1】:就HttpOnly
、Max-Age
和Secure
si 的相关性而言,这些都是为了帮助减轻主要来自客户端的风险,例如客户端脚本访问受保护的cookie(如果浏览器支持它),用于通过安全通信进行传输并通过 javascript 限制访问。
你肯定需要在源头设置这些,就像我们的例子中的 spring-boot 应用程序一样。我不知道操纵 cookie 道具背后的原因,但无论如何,除了带有签名的 jwt 令牌声明之外,您不会验证这些。
签名 jwt 的美妙之处在于,即使有人能够窃取它,除非他拥有签名密钥,否则它将无法使用。所以你的代币对你来说是安全的。
恕我直言,jwts 不是供客户端读取/解密或使用它的,只是您应该收到它,从而验证调用者。
为了增加您的安全性,可以使用org.jasypt.util.text.StrongTextEncryptor
加密您的signed jwt
,这样它对除您之外的任何人都一文不值。
如果您使用,您还可以为 access
和 refresh
令牌保留不同的签名密钥。
【讨论】:
以上是关于在身份验证期间使用 JWT 令牌反序列化 cookie 无法正确反序列化的主要内容,如果未能解决你的问题,请参考以下文章
从多页应用程序进行身份验证后,如何在初始下载期间将 JWT 令牌加载到 React?
在测试期间使用 Django Rest + JWT 进行身份验证