概述
OAuth 通过分离客户端与资源所有者的角色,为客户端-服务器认证模型引入了授权层。在 OAuth 中,客户端请求访问某些资源;这些资源由资源所有者所控制,并托管在资源服务器上。在访问这些受保护资源时,客户端不是使用资源所有者的凭据,而是先获取一个访问令牌 - 这种凭据代表了一组特定的访问属性,例如范围和生命周期。在资源所有者的批准下,一台授权服务器会将访问令牌颁发给客户端。之后,客户端就使用该访问令牌,来访问资源服务器上托管的受保护资源。
在比较早期、比较受限的客户端-服务器认证模型中,客户端会先使用资源所有者的凭据与服务器进行认证,然后再请求某一访问受限的资源(受保护资源)。为了给应用提供访问权限,资源所有者需要与这些应用分享他们的凭据。这造成了若干问题和限制:
- 应用需要存储资源所有者的凭据,以备将来使用,而这一凭据通常是明文密码。
- 服务器需要支持密码认证,而密码本身就不甚安全。
- 对于资源所有者拥有的受保护资源,应用获取的访问权限过于宽泛。资源所有者无法限制访问的持续时间和范围。
- 资源所有者常常不顾安全最佳实践,在其它无关的服务中也使用相同的密码。这种密码的复用,意味着一项服务的漏洞或泄露,可能会对完全无关的服务产生安全影响。
- 资源所有者如果想撤销单个应用的访问权限,就不得不撤销所有第三方应用的访问权限。并且,这种撤销只能通过更改密码来实现。
- 任何应用被攻陷,都会导致终端用户的密码,以及受该密码保护的所有数据,一起被攻陷。
而在 OAuth 中,终端用户(资源所有者)可以授权某一打印服务(客户端)访问他们存储在某一照片分享服务(资源服务器)上的受保护的照片,而无需告诉打印服务他们的用户名和密码。相反,他们会直接与某一受照片分享服务信任的服务器(授权服务器)进行认证,后者则会颁发打印服务所委托的特定凭据(访问令牌)。
这种关注点分离还有一个好处:应用的开发者无需修改自己的应用,就能享受到更高级的用户认证方法,例如多因素认证,甚至是无密码认证。应用不需要考虑任何一种认证机制的实现细节,因为授权服务器接管了用户认证的全部逻辑。授权服务器也因此能够全权管理用户认证的策略,并且甚至不需要与应用协调,也能够在未来改变这些策略。
这一授权层还能够简化资源服务器判断请求是否被授权的流程。传统上,在认证客户端后,每台资源服务器在每次 API 调用时,都要进行策略评估,才能知晓客户端是否获得授权。在分布式系统中,要么这些策略得同步到所有资源服务器上,要么每台资源服务器都必须调用中央策略服务器来处理请求。而在 OAuth 中,只有在授权服务器创建了新的访问令牌时,资源服务器才需要进行策略评估。如果访问令牌本身就已经表明了访问被授权,那么资源服务器就根本不需要进行策略评估,只需要验证访问令牌即可。这种简化流程既适用于应用代表资源所有者的情况,也适用于应用代表自己的情况。
OAuth 是授权协议,而非认证协议。访问令牌代表的是授予客户端的权限。一种常见的做法是,客户端向专门的 API 展示访问令牌,API 返回资源所有者的用户标识符,然后客户端再将该 API 返回的结果作为认证的代表。这种做法不属于 OAuth 的标准或安全考量,资源所有者也未必考虑过这种做法。在采用这种做法前,实现者应该仔细查阅资源服务器的文档。
本规范被设计为与 HTTP([RFC9110])一起使用。在 HTTP 以外的协议中使用 OAuth 不在本规范的范围内。
自 2012 年 10 月 OAuth 2.0 授权框架([RFC6749])发布以来,它被这些文档所更新:用于原生应用的 OAuth 2.0([RFC8252])、OAuth 安全当前最佳实践([I-D.ietf-oauth-security-topics])以及用于浏览器应用的 OAuth 2.0([I-D.ietf-oauth-browser-based-apps])。OAuth 2.0 授权框架:不记名令牌使用([RFC6750])也被([I-D.ietf-oauth-security-topics])所更新。本规范结合了上述所有文档的信息,并且移除了([I-D.ietf-oauth-security-topics])中已被发现不安全的功能。