OAuth 2 和 OAuth 2.1 之间的差异

OAuth 2 和 OAuth 2.1 之间的差异

OAuth 2.1 整合了自 Oauth 2 发布以来八年来学到的最佳实践。最初的 OAuth 2.0 规范于 2012 年 10 月作为 RFC6749 和 RFC6750 发布。它取代了 2010 年 4 月发布的 OAuth 1.0。在随后的几年中,对 OAuth 2 进行了许多扩展和修改。

新的 OAuth 规范已经提出,目前正在讨论中。目前,该规范最近一次更新是在 2020 年 7 月 30 日。如果获得批准,OAuth 2.1 将淘汰 Oauth 2.0 的某些部分,并强制实施安全最佳实践。OAuth 2.0 规范的其余部分将被保留。

这一点值得重复。不会添加任何新内容。这是 OAuth 2.1 的明确设计目标。.

本文假定您是开发人员或具有类似的技术经验,并且熟悉 OAuth 和各种相应标准中使用的术语。如果你想了解 OAuth 以及为什么考虑使用它,维基百科是一个很好的起点。本文介绍了对 OAuth 的建议更改,如果您在应用程序中使用 OAuth 或构建实现 OAuth 的软件,这些更改可能会影响您。

为什么选择 OAuth 2.1?

OAuth 2.0 发布已经有很长时间了,因此合并点发布将有助于简化实施。正如 OAuth 2.1 草案规范的作者之一 Aaron Parecki 在博客文章中概述的那样:

我对 OAuth 2.1 的主要目标是捕获 OAuth 2.0 中的当前最佳实践以及它以单一名称建立的扩展。这也意味着这项工作本身不会定义任何新行为,它只是为了捕获其他规范中定义的行为。它也不会包括任何被认为是实验性的或仍在进行中的东西。

OAuth 2.1 不是 OAuth 2.0 的抓取和重建。相反,OAuth 2.1 捕获并整合了过去八年对 OAuth 2.0 所做的更改和调整。特别关注更好的默认安全性。它确立了最佳实践,并将作为今后的参考文件。

以下是从正在进行的邮件列表讨论中提取的建议描述:

根据设计,[OAuth 2.1] 不会为被替换的 OAuth 2.0 规范中已经存在的功能引入任何新功能。

许多详细信息来自 OAuth 2.0 安全当前最佳实践文档。在安全最佳实践的名义下,一些更有问题的赠款将被取消。

归根结底,OAuth 2.1 的目标是有一个文档来解释如何最好地实现和使用 OAuth,作为客户端和授权服务器。开发人员不再需要在多个 RFC 和标准文档中搜寻以了解应如何实现或使用特定行为。

OAuth 2.1 将如何影响您?

如果您在应用程序中使用 OAuth,请不要惊慌。

如上所述,围绕此规范的讨论过程正在进行中。一份草案于 7 月中旬发布到 IETF 邮件列表中,并于 2020 年 7 月被 OAuth 工作组通过。截至编写本报告时,正在对草案进行审查和微调。

您可能会问,什么时候可用?简短的回答是 “没人知道”。

长答案是 “真的,没有人知道。不过,我们似乎在这个过程中相处得很好”。

即使在 OAuth 2.1 发布之后,也可能需要一段时间才能广泛实施。省略的赠款可能会得到永远的支持,并带有唠叨或警告。规范的确切更改仍在讨论中,RFC 的发布将在未来进一步进行。最后,当 OAuth 2.1 发布时,如果满足你的需求,你可以继续使用 OAuth 2.0 服务器。

也就是说,当 OAuth 2.1 发布时,对在其应用程序中使用 OAuth 进行身份验证或授权的任何人的最大影响将是适应删除两个 OAuth 2.0 指定授权:隐式授权和资源所有者密码凭据授权。

从 OAuth 2.0 到 OAuth 2.1 有什么变化?

RFC 草案中有一节概述了 OAuth 2.0 和 OAuth 2.1 之间的主要变化。该部分可能未捕获更改,但作者的目标是记录那里的所有正式更改。有六个这样的变化:

  • 授权代码授予使用 PKCE (RFC7636) 中的功能进行扩展,因此根据此规范使用授权代码授予的默认方法需要添加 PKCE 参数;
  • 必须根据 OAuth 2.0 安全当前最佳实践的第 4.1.3 节使用精确字符串匹配来比较重定向 URI;
  • 根据 OAuth 2.0 安全当前最佳实践的第 2.1.2 节,此规范中省略了隐式授权("response_type=token")
  • 根据 OAuth 2.0 安全当前最佳实践的第 2.4 节,此规范中省略了资源所有者密码凭据授予;
  • 持有者令牌用法根据 OAuth 2.0 安全当前最佳实践的第 4.3.2 节省略了在 URI 查询字符串中使用持有者令牌;
  • 刷新令牌必须受发件人限制或一次性使用,如 OAuth 2.0 安全当前最佳实践第 4.12.2 节;

PKCE 全称是 Proof Key for Code Exchange, 在 2015 年发布, 它是 OAuth 2.0 核心的一个扩展协议, 所以可以和现有的授权模式结合使用,比如 Authorization Code + PKCE, 这也是最佳实践,PKCE 最初是为移动设备应用和本地应用创建的, 主要是为了减少公共客户端的授权码拦截攻击。

呵呵,好多。让我们依次检查其中的每一个。但在此之前,让我们定义一下本文其余部分中使用的几个术语。

  • Client:用户与之交互的一段代码;浏览器、本机应用程序或 SPA(单页应用程序)都是客户端。
  • OAuth server:实现 OAuth 规范。它具有或可以获取有关哪些资源可供客户端使用的信息。在 RFC 中,此应用程序称为 授权服务器。这也称为身份提供程序。大多数用户称之为“我登录的地方”。
  • Application server:不具有任何身份验证功能,而是将登录请求委托给 OAuth 服务器。它有一个允许 OAuth 服务器识别它的 id。

OAuth 2.1 更改:授权代码授权需要 PKCE

授权代码授予使用 PKCE (RFC7636) 中的功能进行扩展,因此根据此规范使用授权代码授予的默认方法需要添加 PKCE 参数

哇,好多。让我们分解一下。授权代码授予是最常用的 OAuth 授权之一,也是最安全的。如果您喜欢流程图[1],这里有一篇文章使用图表解释授权代码授予,并逐步完成授权。

代码交换证明密钥 (PKCE) RFC 于 2015 年发布,它扩展了授权代码授权,以便在部分授权流通过非 TLS 连接发生时防止攻击。例如,如果本机应用程序的组件之间存在通信,则会发生这种情况。

如果 TLS 存在漏洞,或者用户的路由器固件已受到威胁,并且正在欺骗 DNS 或将 TLS 降级为 HTTP,则也可能发生此攻击。PKCE 需要生成额外的一次性代码并将其发送到 OAuth 服务器。此代码验证请求未被截获或修改。

OAuth 2.1 草案规范要求在每次授权代码授予时使用 PKCE 质询,以防止授权代码被攻击者劫持并用于获取令牌。

OAuth 2.1 更改:必须使用精确字符串匹配来比较重定向 URI

必须根据 OAuth 2.0 安全当前最佳实践的第 4.1.3 节使用精确字符串匹配来比较重定向 URI

某些 OAuth 授权(尤其是授权代码授权)配置了一个或多个重定向 URI。然后,当授权开始时,客户会请求其中一个。授权成功后,OAuth 服务器会将客户端发送到请求的重定向 URI

现在,在此重定向 URI 列表中支持通配符会很方便。在 FusionAuth,我们听到了希望简化开发或CI环境的人的这一要求。每次启动新服务器时,都需要更新重定向 URI 配置以包含新的 URI。

例如,如果 CI 系统为每个功能分支构建一个应用程序,则它可能具有主机名,假设功能分支包含问题 #1551 的修补程序。如果我想使用授权代码授予登录,则必须更新 OAuth 服务器的重定向 URI 设置以包含该重定向 URI:dans-sample-application-1551.herokuapp.comhttps://dans-sample-application-1551.herokuapp.com/oauth-callback

当下一个功能分支构建发生时,比如说对于错误 #1552,我必须添加等等。显然,将重定向 URI 设置为通配符值会更容易,例如。如果是这种情况,OAuth 服务器可以接受与该模式匹配的任何 URL。https://dans-sample-application-1552.herokuapp.com/oauth-callbackhttps://dans-sample-application-*.herokuapp.com/oauth-callback

通配符重定向 URI 的另一个用例发生在最终目标页面需要动态参数时,例如。这些通常在 OAuth 进程开始之前追加到重定向 URI。但是,如果没有通配符,具有动态参数的 URL 将与任何配置的重定向 URI 不匹配,因此重定向失败。trackingparam=123&specialoffer=abc

但是,允许对重定向 URI 进行通配符匹配存在安全风险。如果重定向 URI 匹配灵活,攻击者可以将用户发送到由他们控制的开放重定向服务器,然后发送到恶意目标。OWASP 还讨论了这种开放重定向服务器的危险。虽然此攻击需要以某种方式破坏请求,但对重定向 URI 使用精确匹配可以消除此风险,因为重定向 URI 始终是已知值。

OAuth 2.1 更改:删除了隐式授权

根据 OAuth 2.0 安全当前最佳实践的第 2.1.2 节,此规范中省略了隐式授权(“response_type=令牌”)

隐式授权在单页应用程序 (SPA) 中使用时本质上是不安全的。如果使用此授权,则访问令牌将公开给与 SPA 一起在浏览器中运行的任何 JavaScript。如果你不小心,你会得到一个访问令牌,该令牌位于 URL 片段中,存储在本地存储中,或放入非 HttpOnly cookie 中。在所有情况下,都允许获取访问令牌的攻击者访问资源,就像他们是原始用户一样。这不是一个好情况。

访问令牌不一定是一次性使用的,并且可以存活几分钟到几天,具体取决于 OAuth 服务器的配置方式。如果它们被盗,它们保护的资源将不再安全。你可能会想 “好吧,我的网站上没有任何恶意的 JavaScript”。是否确定?您是否审核了所有代码及其依赖项、依赖项和依赖项?您是否会自动审核代码?广泛的依赖树可能会导致不可预见的安全问题:有人接管了一个开源节点库,并添加了下载数百万次的恶意代码。

这是 一篇关于将隐式授权用于 `SPA` 的最不安全方式的文章[2]。在此情况下,访问令牌作为 HttpOnly cookie 提供给 SPA。最后,它基本上重新创建了授权代码授权,说明了隐式授权是如何无法实现安全的。

OAuth 2.1 规范草案省略了隐式授权。这意味着任何实现 OAuth 2.1 的软件都不必实施此授权。如果在应用程序中使用此授权,如果要符合 OAuth 2.1,则必须将其替换为其他授权。

OAuth 2.1 更改:已删除资源所有者密码凭据授予

根据 OAuth 2.0 安全当前最佳实践的第 2.4 节,此规范中省略了资源所有者密码凭据授予

此授权已添加到 OAuth 2.0 规范中,旨在更轻松地迁移到符合 OAuth 的服务器。在此授权中,应用程序服务器接收用户名和密码(或其他凭证),并将其传递给 OAuth 服务器。下面是 一篇分解资源所有者密码凭据授予的每个步骤[3] 的文章。

此赠款通常用于本机移动应用程序。虽然此授权使迁移到 OAuth 变得更加容易,只需最少的应用程序更改,但它并不遵循典型的委派模式。毕竟,应用程序服务器对用户的凭据具有完全访问权限,这正是 OAuth 旨在避免的。您不能再将保护用户凭据和数据的工作留给 OAuth 服务器。获得此授权后,必须确保应用程序后端同样安全。

如果您有使用此授权的移动应用程序,则可以更新客户端以使用 PKCE 使用授权代码授权,或者继续使用符合 OAuth 2.0 的系统。

OAuth 2.1 更改:查询字符串中没有持有者令牌

持有者令牌用法根据 OAuth 2.0 安全当前最佳实践的第 4.3.2 节省略了在 URI 查询字符串中使用持有者令牌。

持有者令牌(也称为访问令牌) 允许访问受保护的资源,因此必须受到保护。它们被称为持有者令牌,因为只需拥有它们就可以访问。它们就像一套房子的钥匙。

如今,大多数令牌都是 JWT。客户端安全地存储它们,然后使用它们对应用程序服务器进行 API 调用。然后,应用程序服务器使用该令牌来确保调用 API 的客户端具有适当的许可权。在RFC 6750 中首次定义时,标头、POST 正文或查询字符串中允许使用标记。OAuth 2.1 草案禁止在查询字符串中发送持有者令牌。

查询字符串以及 URL 中的任何字符串(更一般地说)从来都不是私有的。在页面上执行的 JavaScript 可以访问它。URL 或其组件可以记录在服务器日志文件、缓存或浏览器历史记录中。一般来说,如果您想通过互联网私下传递信息,请不要在URL 中使用任何内容。相反,请使用 TLS 并将敏感信息放在POST 正文或 HTTP 标头中。

OAuth 2.1 更改:限制刷新令牌

刷新令牌必须受发件人限制或一次性使用,如 OAuth 2.0 安全当前最佳实践第 4.12.2 节

刷新令牌允许客户端检索新的访问令牌,而无需资源所有者重新进行身份验证。 如果需要访问资源的时间超过访问令牌的生存期,或者需要不频繁的访问,刷新令牌可以提供帮助。可能使用刷新令牌的一个示例是当用户登录到其电子邮件数周或数月时。每次访问令牌过期时,客户端都可以提供刷新令牌并获取新的访问令牌。

刷新令牌的生存期比访问令牌更长,并且具有更高的特权级别,因为它们可用于创建全新的访问令牌。因此,在保护刷新令牌时应格外小心。切勿在不同设备之间共享刷新令牌。

如果它们被攻击者获取,他们可以随意创建访问令牌。显然,此时访问令牌保护的资源将不再受到保护。作为如何保护刷新令牌的示例,下面是一篇使用授权代码授予的文章,该授权使用具有受限 cookie 域的 HttpOnly cookie 存储刷新令牌,您可以在 此处了解有关 `FusionAuth` 访问和刷新令牌[4] 的更多信息。

OAuth 2.1 草稿为刷新令牌提供了两个选项:它们可以是 一次性使用 的,也可以通过 加密绑定绑定 到发送方。

  • 使用一次性刷新令牌时,在使用刷新令牌(称为刷新令牌 A)检索新的访问令牌后,它将变为无效。OAuth 服务器可能会发送新的刷新令牌(称为刷新令牌 B)以及请求的访问令牌。新传递的访问令牌过期后,客户端可以使用刷新令牌 B 请求另一个访问令牌,并接收新的访问令牌和刷新令牌 C,依此类推。更改为一次性使用刷新令牌可能需要更改客户端代码,以便在每次刷新访问令牌时存储新的刷新令牌。

  • 另一个选项是确保 OAuth 服务器以加密方式将刷新令牌绑定到客户端“OAuth 2.0 安全当前最佳实践” 文档中提到的选项包括 OAuth 令牌绑定、相互 TLS 身份验证 RFC 8705 和 DPoP 等。所有这些绑定方法都可确保请求来自向其颁发刷新令牌的客户端。

总而言之,OAuth 2.1 草案要求 OAuth 服务器通过要求刷新令牌一次性使用或使用客户端关联的加密证明来保护刷新令牌。这两个选项都可以保护这些强大的令牌不被攻击者使用。

什么不变?

这些是拟议的 OAuth 2.1 草案的主要变化。 OAuth 2.1 规范建立在 OAuth 2.0 RFC 的基础上,继承了所有未明确省略或更改的行为。例如,通常用于服务器到服务器通信的客户端凭据授予仍将可用。

您现在可以使用 OAuth 2.1 吗?

截至目前,没有任何印有 “OAuth 2.1” 的印章。而且草案规范尚未最终确定。但是,如果您遵循有关安全性的最佳实践,则可以从此合并草案中获益,并为发布做好准备。

编写客户端应用程序时,请避免隐式授予和资源所有者密码凭据授予。

确保您的 OAuth 服务器执行以下操作:

  • 每当使用授权代码授予时,都使用 PKCE
  • 确保使用完全字符串匹配(而不是通配符或子字符串匹配)来比较重定向 URI。
  • 确保查询字符串中永远不会存在持有者令牌。
  • 限制刷新令牌,方法是一次性使用或让它们受发送方约束。

OAuth 的下一步是什么?

预测是非常困难的,特别是如果它是关于未来的。- 尼尔斯·玻尔

OAuth 2.1 仍在 IETF OAuth 邮件列表中讨论。如果您有兴趣关注或影响此 RFC,请查看讨论存档以加快速度。您也可以加入邮件列表。

除了 OAuth 2.1 之外,如前所述,OAuth 2.1 旨在整合安全最佳实践,但不影响OAuth 2.0 的大部分其余部分,还有一个 “下一代” 工作组,从头开始重新构想授权谈判和授权协议。该协议旨在涵盖与 OAuth2 相同的用例,但明确排除了向后兼容性

“尽管这项工作的工件并不打算或预期与 OAuth 2.0 或 OpenID Connect 向后兼容,但该小组将尝试在可能的情况下简化从 OAuth 2.0 和 OpenID Connect 到新协议的迁移。

GNAP 规范比 OAuth 2.1 规范更远。

原文地址:

  • 【Differences between OAuth 2 and OAuth 2.1】,https://fusionauth.io/learn/expert-advice/oauth/differences-between-oauth-2-oauth-2-1