我正在开发一个带有 REST 后端的 SPA,并希望拥有基于简单令牌的身份验证。支持 REST 的目标是无状态。我将解释安全模型并尝试参考设计期间做出的决策的所有来源。希望对整个设置发表评论并回答一些具体问题。
抽象的
身份验证将在专用端点(例如 /auth/login)上完成。登录信息将作为 JSON 对象传递。信息将包含用户名和密码。成功登录后,将颁发一个签名的 JWT 令牌。此令牌将用于后续访问 REST API。
应用程序将使用 HTTPS,我控制所有子域。
细节
智威汤逊
- 包含用户名、发布时间和到期时间
- 包含有关应用程序内部角色成员资格的声明
- 包含一个 CSRF 令牌(从加密安全的伪随机生成器随机生成)
- 使用仅对服务器可用的 HMAC (SHA256) 密钥进行签名
到期
将发出一个具有较短到期时间(例如 30 分钟)的令牌。每次请求(滑动窗口到期)时都会发布一个更新的令牌,并在合理的截止日期(例如 8 小时)内发布。流程如下:
- 初始登录请求将发出一个有效期为 30 分钟的令牌
下一个请求将检查令牌是否已过期。如果过期,访问将被阻止。如果没有,请求将被满足。届时将检查令牌的年龄。
- 如果年龄在最后期限内(小于 8 小时),将生成更新的令牌,其中包含另外 30 分钟的新到期时间。发行时间与原代币相同。
- 如果令牌的年龄超过截止日期,则不会生成更新的令牌,用户需要再次登录。
理由:我想保护一个过期时间短的令牌,以防它被泄露。我也不想强迫用户经常重新登录。攻击者需要在小于令牌到期时间的时间范围内请求新令牌。如果攻击者设法做到这一点,他/她可以使用令牌的最长时间由截止日期定义。用户可以在设定的最后期限内保持在线。对于商业申请,8 小时或一天的截止日期就足够了。这个实现是否足够安全?可能的缺点和漏洞是什么?
智威汤逊运输和存储
JWT 将作为 httpOnly cookie 传输到客户端,并将存储在浏览器的 Cookies 存储库中。
基本原理:保护令牌免受 XSS 攻击,如果将令牌保存在 localStorage/sessionStorage 中,则会危及令牌。这是根据本文的建议。除了将实现开放给 CSRF 攻击之外,这种方法有什么问题吗?
CSRF 保护
将 JWT 令牌存储在 cookie 中将使实现面临 CSRF 攻击。为了缓解这个问题,实现了双重提交 cookie 方法。CSRF 令牌生成并包含在 JWT 令牌中。此令牌还以对登录请求的响应的 JSON 对象的形式提供给客户端应用程序。应用程序会将 CSRF 存储在 localStorage 中,并将其与自定义标头中的每个请求一起提交。
基本原理:根据参考本文对这个问题的回答,为了有效的 CSRF 保护,有必要将 CSRF 令牌与会话标识/身份验证 cookie 进行加密绑定。如果我在 JWT 中包含一个令牌,它是否被认为与安全会话加密相关?
从概念上讲,你觉得这个实现有什么问题吗?