将 id_token 传递给浏览器代码是不安全的吗?

Is it insecure to pass id_token to browser code?

我一直在深入研究 OAuth2 / OpenID Connect(OIDC),在很多方面我觉得自己更聪明了,但在很多方面,我担心一个简单的错误会让我变得脆弱。我正在构建超级标准的商业应用程序。是时候问路了:

我得到 id_tokenaccess_tokenrefresh_token

我有一百万个问题,但让我们从基础开始:

  1. 是否可以将id_token发送到浏览器中的react代码并存储在Session Storage中?否则 UI 应该如何知道有关登录者的信息?

  2. 如果我有 id_token,我还关心 /userinfo 端点吗?我的猜测是没有。

  3. 每次 UI 调用 api 它都会传递授权码? spring 代码是否每次都依次调用 /oauth/token? Spring 代码是否应该(或是否)缓存授权代码和返回的令牌之间的关系?

您只要求 openid 范围,那么为什么需要访问权限和刷新令牌?并且由于您希望 React 应用程序使用 ID 令牌,我建议您使用隐式流 - 将 ID 令牌直接获取到您的前端。

  1. 您可以将令牌保存在 SessionStorage 中。
  2. ID 令牌可能包含您需要的所有信息,因此如果 /userinfo 端点没有提供您想要的任何其他信息,您可以忽略它。
  3. 出于安全原因,授权码只能使用一次。所以拿到代币之后再留着是没有意义的。如果你想保持后端 API 无状态(无会话),你可以使用访问令牌。那么最好有可能在 auth 服务器上配置 backend-specific 范围或仅使用 /userinfo 端点来获取有关用户的信息。或者,如果您想将前端和后端视为一个 OAuth2 客户端(相同的 ID 令牌受众)并且您在后端只需要用户身份,则可以使用 ID 令牌。

SPA 的推荐流程是 implicit,实际上使用 oidc-client-js 库是有意义的。在此流程中,access_token 直接返回给客户端,无需额外的授权代码步骤。没有发出 refresh_token

在此拓扑中,令牌存储在客户端的 sessionStorage 中(默认情况下,但这是可插入的),您通过在授权 header 中传递 access_token 向 back-end 发出请求] (通常)。令牌更新不是通过刷新令牌完成的,而是通过后台静默授权端点调用自动完成的。这种方法的缺点是,如果您的应用程序通过 XSS 遭到破坏,那么您的令牌将立即可供攻击者使用。

但是,如果您更喜欢使用 server-side 流程(与表单 post 响应类型混合)和 (https-only) cookie 身份验证,那么您可以。客户端代码只需要实施某种 CSRF 缓解措施,但根本不需要了解 OpenID Connect 问题。