OAuth 2.1 已经到来:你需要了解的内容
OAuth 2.1 规范已被提上日程。让我们来探索 OAuth 2.0 和 OAuth 2.1 之间的关键区别,以及它们在 Logto 的采用情况。
介绍
自从 OAuth 2.0 (RFC 6749) 在 2012 年发布以来,网页和移动应用程序的世界已经发生了很大的变化。人们从桌面端转向了移动设备,而单页应用程序(SPAs)现在非常流行。同时,我们也看到了很多新的框架和网络技术的出现。随着这些变化,安全挑战也步步升级。为了跟上最新的网络技术,诸如代码交换证明密钥(PKCE)等新的 RFC 不断发布,以增强 OAuth 2.0。将所有满足今天安全需求的最佳实践汇总在一起变得至关重要,这也是 OAuth 2.1 推出的原因。
在即将发布的 OAuth 2.1 中,OAuth 工作组旨在将所有最佳实践和安全建议汇总到一个文档中。在 Logto,我们紧紧拥抱 OAuth 的最新标准和最佳实践。在本文中,我们将探讨 OAuth 2.0 和 OAuth 2.1 之间的关键区别,以及它们在 Logto 的使用情况。
PKCE 现在对所有使用授权码流程的 OAuth 客户端都要求
OAuth 2.1 中最显著的变化之一是,现在对所有使用授权码流程的 OAuth 客户端都要求使用代码交换证明密钥(PKCE)。PKCE 是一个安全扩展,能够防止授权码拦截攻击。这对于移动应用和单页应用程序(SPAs)尤其有用,因为客户端密钥无法安全存储。
根据是否能够安全存储密钥,OAuth 客户端可以分为两种不同类型:
-
机密客户端:这些客户端可以安全存储密钥,如服务器渲染的 web 应用程序和 web 服务器。所有与授权相关的请求都是从服务器端完成的,暴露客户端密钥的风险较低。
-
公共客户端:这些客户端无法安全存储密钥,例如移动应用和 SPAs。客户端密钥很容易从客户端代码中被提取,因此很难保护其免受攻击者的威胁。
对于公共客户端,PKCE 是必须具备的安全措施。它确保授权码只能由发起授权请求的客户端兑换。
PKCE 的工作原理是通过生成一个随机的代码验证器和一个基于代码验证器的代码挑战。代码验证器被发送到授权服务器,而代码挑战则在交换授权码获取访问令牌时用于验证代码验证器。
在 OAuth 2.1 中,PKCE 对所有使用授权码流程的 OAuth 客户端无论其是否是机密的,都变成了强制要求。这一关键调整保障了统一防止潜在的授权码拦截攻击。
在 Logto,PKCE 验证流程会自动为公共和机密客户端激活。
对于 SPAs 和移动应用程序,PKCE 是 Logto 中保护授权码流程必须的安全措施。任何缺少代码挑战的授权请求都会被 Logto 的授权服务器立即拒绝。
对于机密客户端(传统 web 应用),为了增强对遗留系统的兼容性,Logto 仍然允许在授权请求中省略代码挑战。尽管如此,我们强烈建议机密客户端仿照公共客户端在授权请求中加入代码挑战,采用 PKCE。
重定向 URI 精确匹配
重定向 URI(统一资源标识符)是授权服务器在身份验证和授权过程完成后将用户重定向回的特定端点或 URL。
在 OAuth 流程中,客户端应用程序会在初始授权请求中包含一个重定向 URI。当用户完成身份验证过程后,授权服务器会生成包含授权码的响应,并将用户重定向回指定的重定向 URI。任何与原始重定向 URI 的偏差都可能导致授权码或令牌泄露。
重定向 URI 的精确字符串匹配首次在 [OAuth 2.0 安全最佳现有实践](https://tools.ietf.org/html/draft-ietf-oauth-security- topics) 第 4.1 节中介绍。这一实践确保了重定向 URI 必须与在授权服务器中注册的一致。任何与注册重定向 URI 不符的情况都会导致错误响应。
我们收到了社区中许多关于实现通配符匹配重定向 URI 的请求。虽然通配符匹配可以为管理大量子域或路径的开发者带来便利,尤其是在有大量随机子域的情况下,但它也引入了诸如开放重定向攻击之类的安全风险。有关缺少重定向 URI 验证所带来的危险的实用说明,请参阅我们的 [OAuth 安全简要回顾](https://blog.logto.io/oauth- security-recap/#redirect-uri) 博客文章。
根据 OAuth 2.1 严格的安全标准,Logto 使用重定向 URI 的精确字符串匹配。这一决定优先考虑了 OAuth 流程的安全性。相较于使用通配符匹配,我们鼓励开发者在 Logto 授权服务器中注册所有可能的重定向 URI。这确保了对重定向 URI 的彻底验证,并有助于减轻潜在的安全漏洞风险。
隐式流程已被弃用
OAuth 2.0 中的隐式授权流程设计用于 SPAs,在用户认证后,访问令牌会直接在 URL 片段中返回。这种方法方便,因为它避免了额外的令牌交换步骤,让客户端直接接收令牌。
然而,这种便利性也带来了弊端。访问令牌可能会通过浏览器历史记录、引用头或其他方式暴露给未授权的方,从而更容易发生安全漏洞——尤其是当访问令牌长期有效的时候。例如,如果授权请求被恶意方拦截,他们可以轻松地从 URL 片段中提取访问令牌并伪装成用户。
在 [OAuth 2.0 安全最佳现有实践](https://tools.ietf.org/html/draft-ietf-oauth- security-topics) 中明确指出:
客户端不应使用隐式授权流程(响应类型 "token")或授权响应中颁发访问令牌的其他响应类型。
因此,隐式流程已正式从 OAuth 2.1 规范中移除。
在 Logto 中,授权码流程与 PKCE 是唯一支持的 SPAs 和移动应用程序流程。授权码流程通过交换授权码提供了更安全的方式来获取访问令牌。
资源所有者密码凭证(ROPC)授权流程被废弃
资源所有者密码凭证(ROPC)授权流程允许客户端用用户的用户名和密码兑换访问令牌。它最早在 OAuth 2.0 规范中被引入,以支持诸如 HTTP 基本认证或无法使用更安全的 OAuth 令牌化流程的遗留应用程序。
ROPC 授权流程在 OAuth 2.0 规范中因为其安全风险而被标记为不推荐。用户的凭证会暴露给客户端应用程序,可能导致潜在的安全漏洞。客户端应用程序可以存储用户的凭证,如果客户端受到攻击,用户的凭证可能会泄露给攻击者。
后来在 [OAuth 2.0 安全最佳现有实践](https://tools.ietf.org/html/draft-ietf- oauth-security-topics) 第 2.4 节中,更进一步强调了不应使用 ROPC 授权流程的禁令。因此,ROPC 授权流程已被自 OAuth 2.1 规范中移除。
由于 ROPC 授权流程的高安全风险,Logto 从未支持它。如果你仍在遗留应用程序中使用直接的用户凭证流程,我们强烈建议迁移到更安全的方法,如授权码流程或客户端凭证授权流程。Logto 提供了各种 SDK 和教程,帮助你轻松地将这些安全的 OAuth 流程集成到你的应用程序中。
我们理解开发者可能希望设计或自行托管自己的用户登录界面,以实现最佳的产品体验。在 Logto,我们提供了一系列登录体验(SIE)定制选项,包括品牌设置和自定义 CSS。此外,我们还有几个进行中的项目,如自带用户界面(BYOUI)和直接登录,提供更多灵活性,让开发者在保持 OAuth 流程安全的同时,能够使用自带的登录界面。
结论
OAuth 2.1 是 OAuth 协议的最新升级,旨在应对当今的安全挑战,并满足现代 web 和移动应用程序的需求。OAuth 工作组正在积极更新和完善 OAuth 2.1,以确保其符合最新的安全标准和最佳实践。最新的草案 OAuth 2.1 11 于 2024 年 5 月发布,标志着朝着最终敲定的方向迈出了重要一步。随着广泛采用的临近,我们强烈推荐大家遵循在 OAuth 2.1 中概述的最佳实践,以增强安全性并改善用户体验。