【问题标题】:OpenId Connect renew access_token in SPAOpenId Connect 在 SPA 中更新 access_token
【发布时间】:2018-11-07 22:31:04
【问题描述】:

尝试在由以下组件组成的 Web 应用程序中实现 OpenId Connect

  • 身份提供者
  • 资源服务器
  • 作为客户端的单页应用程序。

身份提供者和资源服务器是同一个应用程序。

SPA 使用密码流获取access_token 并存储到 cookie 中。 access_token 存储到 cookie 中是 security threads,但这是另一回事。

问题

IdP 发出的access_token 30 分钟后过期,SPA 需要更新令牌,无需再次询问用户凭据。

解决方案

IdP 返回 refresh_tokenaccess_token。每当 SPA 从资源服务器获取 401 时,它会将 refresh_token 发送到 IdP 并返回新的 access_token

问题

向 SPA 发送 refresh_tokenbad practice

单页应用程序(通常实现隐式授权)在任何情况下都不应获得刷新令牌。原因是这条信息的敏感性。您可以将其视为用户凭据,因为刷新令牌允许用户基本上永远保持身份验证。因此,您不能在浏览器中拥有这些信息,它必须安全地存储。

建议的解决方案

当访问令牌过期时,假设用户的 SSO 会话尚未过期,则可以使用静默身份验证来检索新的令牌,而无需用户交互。

当 IdP 和资源服务器是同一个应用程序时,我认为 Silent Authentication 不适用于密码流。 IdP 发出的access_token 只是一条信息,可用于在资源服务器/IdP 到期后对其进行授权,客户端如何说服 IdP 发出新的access_token? (不发送refresh_token

找到使用refresh_token 更新access_tokenangular-oauth2-oidc 库。

在这种情况下,续订access_token 的最佳做法/解决方案是什么?

技术细节

  • 身份提供程序 - ASP.NET Core + Openiddict 库。
  • SPA - AngularJs 应用程序。

【问题讨论】:

  • 有什么理由让你避免隐式流?

标签: asp.net-core oauth-2.0 openid-connect openiddict


【解决方案1】:

在之前的回答基础上,最新的 OAuth 工作组guidance for SPAs 不再推荐使用隐式流。

如果您有简单的共享域应用程序(单个域上的 IdP、RS 和客户端),那么您应该考虑完全不使用 OAuth。来自the doc

OAuth 和 OpenID Connect 在这方面几乎没有什么好处 部署场景,所以建议重新考虑是否 在这种情况下,根本需要 OAuth 或 OpenID Connect。会议 身份验证的好处是具有更少的活动部件和更少的 攻击向量。 OAuth 和 OpenID Connect 主要是为 第三方或联合访问 API,因此可能不是最好的 同域场景下的解决方案。

如果您正在在 SPA 中使用 OIDC/OAuth,they recommend 使用 PKCE 的身份验证代码流。

【讨论】:

    【解决方案2】:

    使用资源所有者密码凭据流程会破坏刷新令牌存储参数:SPA 现在必须将资源所有者凭据存储在安全位置,而不是无法将刷新令牌存储在安全位置(假设您希望避免频繁地向用户请求用户名/密码)。隐式授权是为与 SPA 一起使用而设计的,因此最好坚持下去。

    【讨论】:

      【解决方案3】:

      单页应用程序不得接收刷新令牌。这已经在 OAuth 2.0 和 OpenID Connect 中建立了规则。

      我在这里看到的一个不错的选择是使用Implicit Flow。这将建立从您的浏览器到身份提供者的前端通道会话。使用密码授予类型,您会执行反向通道调用 (POST),因此您不会获得此类会话。

      通常这是一个 cookie,它指向有关先前登录状态的信息(这些是身份提供者的具体信息)。随着流程的完成,SPA 将收到access token。如您所见,它将过期。但是一旦发生这种情况,SPA 可以触发另一个隐式流,但这次使用prompt 查询参数。

      提示

      空格分隔、区分大小写的 ASCII 字符串值列表 指定授权服务器是否提示最终用户 重新认证和同意。定义的值为:noneloginconsentselect_account

      如果您的身份提供者维持一个长期的会话(例如:几个小时或几天),或者如果它维持一个记住我的 cookie,SPA 可以使用prompt=none 使其跳过身份提供者的登录步骤。基本上,您将获得基于浏览器的 SSO 行为。

      【讨论】:

      • 谢谢。你的建议看起来不错。我想知道通过iframe 将 IdP 登录页面嵌入客户端页面是否可能/安全?
      • @tchelidze 我会说要避免这种情况并利用浏览器并重定向来完成流程。一些 indeity 提供商可能会避免在 iframe 中加载登录页面(通过设置相关标题)
      • 外部 IdP 通常不希望他的网站在不受信任的环境中加载。但就我而言,IdP、RP 和 RS 是我的。你怎么看?
      • @tchelidze 您可以继续采用这种方法。但将来,您可能希望支持其他身份提供者。所以也要注意这些需求
      猜你喜欢
      • 2013-10-18
      • 2018-03-09
      • 1970-01-01
      • 2015-01-09
      • 2018-01-15
      • 2019-10-15
      • 2020-05-08
      • 2019-03-04
      • 2020-10-23
      相关资源
      最近更新 更多