oauth2.0 将刷新令牌存储在客户端上的何处?

5cnsuln7  于 2022-11-28  发布在  其他
关注(0)|答案(6)|浏览(237)

我的SPA应用程序使用以下体系结构(source):

这假定我的客户端应用程序知道刷新令牌,因为如果不存在用户凭据(例如电子邮件/密码),我需要它来请求新的访问令牌。
我的问题:在我的客户端应用程序中,我应该将刷新令牌存储在哪里?在SO上有很多关于此主题的问题/答案,但关于刷新令牌,答案并不清楚。
访问令牌和刷新令牌不应该存储在本地/会话存储器中,因为它们不是任何敏感数据的存储位置。因此,我会将
访问令牌
存储在httpOnly cookie中(即使有CSRF),而且我需要它来处理大多数对资源服务器的请求。

**但刷新令牌怎么办?**我不能将其存储在cookie中,因为(1)它会随每个请求一起发送到我的资源服务器,这也使它容易受到CSRF的攻击,(2)它会发送具有相同攻击向量的暴露访问/刷新令牌。

我能想到的解决办法有三种:
1)将刷新标记存储在内存中的JavaScript变量中有两个缺点:

  • a)易受XSS攻击(但可能不像本地/会话存储那样明显
  • B)如果用户关闭浏览器选项卡,它将释放“会话”

特别是后一个缺点使得将变成一个坏的UX。
2)将访问令牌存储在会话存储中,并通过Bearer access_token授权头将其发送到资源服务器,然后我可以使用httpOnly cookie作为刷新令牌。

  • a)刷新令牌随着对资源服务器做出的每个请求而暴露给CSRF。

3)将两个令牌都保存在httpOnly cookie中,这具有上述缺点,即两个令牌都暴露于相同的攻击向量。
也许还有其他的方法或者比我提到的缺点更多的方法(请告诉我),但是最终所有的事情都归结为我在客户端的哪里保存我的刷新令牌?是httpOnly cookie还是内存中的JS变量?如果是前者,那么我在哪里放置我的访问令牌?
会超级高兴地得到任何线索,如何做到这一点的最佳方式从人谁熟悉的主题。

wydwbb8l

wydwbb8l1#

您可以在HttpOnly Cookie中安全地存储令牌。
https://medium.com/@sadnub/simple-and-secure-api-authentication-for-spas-e46bcea592ad
如果您担心刷新令牌会过期,可以跳过存储它,根本不使用它只需将访问令牌保留在内存中,并在访问令牌过期时进行静默登录
不要使用Implicit流,因为它是obsolete
SPA最安全的身份验证方式是Authorization Code with PKCE
通常,使用基于oidc-client的现有库比自己构建库要好。

kgsdhlau

kgsdhlau2#

您可以将存取和重新整理这两个Token储存为Cookie。但是重新整理Token必须有特殊路径(例如/refresh)。因此,只会针对对/refresh url的要求传送重新整理Token,而不是针对每个要求(例如存取Token)。

5q4ezhmt

5q4ezhmt3#

将访问令牌存储在会话存储中,并通过一个Bearer access_token授权头将其发送到我的资源服务器,然后我可以使用httpOnly cookie作为刷新令牌。a)刷新令牌随着对资源服务器做出的每个请求而暴露给CSRF。
您可以正确设置CORS policy,以便只接受来自授权服务器的/refresh_token请求。
如果客户端和服务器由同一台计算机提供服务,则可以在Cookie中将标志sameSite设置为true,并包含一个anti-CSRF标记。

xzv2uavs

xzv2uavs4#

如果身份验证提供程序实现了刷新标记循环,则可以将它们存储在本地存储中。
但这意味着每次客户端刷新JWT时,Auth提供程序都应返回一个新的刷新标记。如果试图再次使用一个刷新标记,Auth提供程序还应具有使后代刷新标记无效的方法。
https://auth0.com/docs/tokens/refresh-tokens/refresh-token-rotation

mepcadol

mepcadol5#

OAuth定义了四种授权类型:授权代码、隐式、资源所有者密码凭据和客户端凭据。它还提供用于定义其他授权类型的扩展机制。
__ RFC 6749 -OAuth 2.0授权框架
Authorization Code进程是为安全的客户端(例如服务器)设计的,它的安全性足以保存Client Secret。如果您的客户端足够安全,可以保存该秘密,只需将Refresh Token放在与您的Client Secret相同的安全存储中。
对于User-Agent中承载的应用程序,情况并非如此(UA)。对于那些,规范建议使用Implicit授权类型,该类型在#符号之后的片段中的Redirection URI之后呈现Access Token。假定您直接在User-Agent中接收令牌,它本质上是一种不安全的方法,除了遵循User-Agent的安全规则之外,您对此无能为力。
您可以将应用程序的使用限制为特定的User-Agent,但这很容易被篡改。您可以将令牌存储在cookie中,但如果UA不遵守公共安全规范,也可以访问该cookie。如果UA实现并提供令牌,您可以将令牌存储在本地存储中,但前提是它遵守规范。
这些隐式间接授权的关键是对UA的信任;否则,最安全的授权类型是授权码,因为它需要在受控环境(应用程序的服务器)上安全可靠地存储机密。
如果您别无选择,只能使用隐式调用,那么就大胆尝试,相信用户使用的是遵循安全协议的安全UA;无论如何,您不对用户错误UA选择负责。

guz6ccqo

guz6ccqo6#

您没有使用最佳的身份验证体系结构。SPA是公共客户端,它无法安全地存储客户端机密或刷新令牌等信息。您应该切换到Implicit Flow,其中不使用刷新令牌。但可以使用Silent Authentication(静默续订)。
我推荐使用OIDC certified library,其中已经为SPA应用进行了分类。我最喜欢的一个:https://github.com/damienbod/angular-auth-oidc-client

相关问题