带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?
Posted
技术标签:
【中文标题】带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?【英文标题】:SPA with refresh tokens stored in cookie - how to configure with IdentityServer4? 【发布时间】:2020-07-02 21:31:32 【问题描述】:我有一个 SPA,它使用长寿命的自包含 JWT 与 API 进行通信以进行身份验证。
SPA 当前正在将此 JWT 存储在本地存储中。
除了从安全角度来看这非常糟糕之外,另一个主要问题是我有办法撤销对 API 的访问(顺便说一句,需要保持无状态)。一个用户拥有一个令牌,他们可以无限期地使用它。
我想开始使用刷新令牌。我知道这些通常不推荐用于 SPA,但是在阅读 The Ultimate Guide to handling JWTs on frontend clients 之后,我相信有一种方法可以安全地做到这一点。
我想要什么:
当用户登录(密码授予)时,服务器仅响应一个短暂的 access_token,但使用刷新令牌设置一个 HttpOnly cookie。 客户端将 access_token 存储在内存中,并在发出 API 请求时使用。 当 access_token 即将到期时,我会向身份验证服务器发出请求以刷新令牌。因为 cookie 是由身份验证服务器设置的,所以它会自动包含在请求中。服务器以我们存储在内存中的更新后的 access_token 进行响应。 如果用户离开 SPA 并稍后返回,我们可以简单地向身份验证服务器发出请求以刷新令牌,这为我们提供了一个全新的令牌(无需在本地存储中存储任何内容)。李>这似乎是最安全的选择,最小化 XRSF 和 CSRF:
如果有人设法将一些代码注入 SPA 并窃取了 access_token,它无论如何都会在 5 分钟后过期。注入的代码永远无法访问 refresh_token。 您无法欺骗用户发出 CSRF API 请求,因为您没有 access_token(访问令牌有效地用作 CSRF 令牌)。 如果有人确实设法获得了对 refresh_token 的访问权限,则可以在身份验证服务器上撤销它。如果这个方法和我想的一样充分证明(请证明我错了!),为什么网上很少提到它?
IdentityServer4 文档似乎没有涵盖这一点。有人可以建议如何实施吗?我希望我可以在客户端配置中按照UseCookiesForRefresh
的行设置一个属性,但没有。
【问题讨论】:
您是否设法使用 RefreshToken 刷新 AccessTokens?请问您如何保护刷新过程中需要的 Spa 中的 client_secret? 【参考方案1】:您可以在用户会话结束(或注销)时使用 ReferenceToken 类型而不是 Jwt Token 来撤销令牌。 Reference Token
您需要在客户端配置中更改 AccessTokenType
new Client
ClientName = "OAuth Test",
ClientId = "TestClientId",
AllowedGrantTypes = GrantTypes.Hybrid,
AccessTokenLifetime = 300,
AllowOfflineAccess = true,
AccessTokenType = AccessTokenType.Reference,
......
当用户注销时,您可以使用以下几行来撤销该会话中生成的所有令牌。
await _interaction.RevokeTokensForCurrentSessionAsync();
【讨论】:
以上是关于带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?的主要内容,如果未能解决你的问题,请参考以下文章
带有 JWT 的 AngularJS 或 SPA - 到期和刷新