Spring Boot 使用访问令牌和刷新令牌,这是安全的吗
问题描述
我正在用Spring Boot和React构建我的第一个Web应用程序。目前我关注的是安全方面。应用程序使用JWT令牌。当用户登录时,后端以授权标头中的短期访问令牌以及存储在HttpOnly Cookie中的长期刷新令牌进行响应。然后将访问令牌存储在本地存储中,并用于进行后续请求。Cookie(包含刷新令牌的Cookie)的路径设置为负责刷新访问令牌的端点,以便它不会随每个由前端发出的请求一起发送。如果访问令牌过期,则后端以401状态进行响应,前端会发送请求到刷新端点。
考虑到这是一个演示应用程序,这种方法有效吗?还是应该使用OAuth2和”后端为前端”或”BFF”?
解决方案
考虑到这是一个演示应用程序,这种方法有效吗?还是应该使用OAuth2和”后端为前端”或”BFF”?
这取决于你想向谁展示。
如果是为了展示你可以确保安全性,我绝对不会展示这个,因为这只会显示你的知识来自于遵循差劲的博文,并且你对于为什么不应该在生产环境中构建此类登录系统没有真正的了解。
《OAuth2.0安全最佳实践》文档建议完全不使用隐式流程,因为返回访问令牌的HTTP重定向存在风险,而没有任何确认客户端已接收到的方式。
如果你明确使用JWT令牌,那么在将令牌直接提供给浏览器时还需要考虑其他严重的风险。
Spring Security中没有这样的实现,而这也是有好的原因的。
- 无法注销用户,删除浏览器中的令牌并不意味着用户已注销。如果其他人拥有该令牌,仍然可以使用。
- 令牌只能过期
- 无法阻止用户
- 无法注销”所有设备”
- 令牌可以通过XSS攻击来窃取
- 没有安全的方式来存储浏览器中的令牌
- 如果用户被欺骗用http而不是https来调用请求,则令牌可以从请求中被窃取。
- 过去几年中JWT库中存在多个安全漏洞
还有很多问题。
JWT原本是用于在私有网络中使用,以减少对颁发者的请求次数。它们应该短期存在(几分钟)以执行一次性请求。它们从未旨在取代会话。
Spring的实施指南《用于基于浏览器的应用程序(SPA)的实施准则》推荐使用类似BFF的私有客户端。
像Google、Facebook等大公司不会将令牌暴露给浏览器,而是在客户端中使用BFF模式和Cookie,主要遵循OpenID连接标准。
因此,如果你打算展示你了解安全性,我会展示适当的安全性。