背景:我已经为OAuth 1.0a和2.0编写了客户端和服务器堆栈。
OAuth 1.0a和2.0都支持两足式身份验证和三足式身份验证,在这种情况下,服务器可以确保用户的身份。(其中由内容提供商确保用户身份)。三足身份验证是授权请求和访问令牌起作用的地方,需要注意的是OAuth 1也具有这些身份。
复杂的一:三足身份验证
OAuth规范的主要目的是让内容提供者(例如Facebook,Twitter等)确保服务器(例如希望代表客户端与内容提供者对话的Web应用)客户端具有某种身份。三足式身份验证提供的功能是无需客户端或服务器就无需知道该身份的详细信息(例如,用户名和密码)的能力。
无需(?)深入了解OAuth的细节:
- 客户端向服务器提交授权请求,以确认客户端是其服务的合法客户端。
- 服务器将客户端重定向到内容提供者,以请求对其资源的访问。
- 内容提供者会验证用户的身份,并经常请求其访问资源的许可。
- 内容提供商将客户端重定向回服务器,通知其成功或失败。该请求包括成功的授权码。
- 服务器向内容提供者发出带外请求,并交换访问令牌的授权代码。
服务器现在可以通过传递访问令牌代表用户向内容提供者发出请求。
每个交换(客户端->服务器,服务器->内容提供程序)都包含对共享机密的验证,但是由于OAuth 1可以在未加密的连接上运行,因此每个验证都无法通过网络传递机密。
正如您所指出的,HMAC已经完成。客户端使用它与服务器共享的机密来为其授权请求签名自变量。服务器接受参数,并使用客户端的密钥对其进行签名,并能够查看其是否为合法客户端(在上面的步骤1中)。
此签名需要客户端和服务器双方就参数的顺序达成一致(因此,他们要对完全相同的字符串进行签名),而有关OAuth 1的主要抱怨之一是,它要求服务器和客户端都进行排序和签名相同。这是很奇怪的代码,或者是正确的代码,或者您得到的401 Unauthorized
帮助很少。这增加了编写客户端的障碍。
通过要求授权请求在SSL上运行,OAuth 2.0完全不需要参数排序和签名。客户端将其秘密传递给服务器,服务器直接对其进行验证。
服务器->内容提供程序连接中存在相同的要求,并且由于SSL消除了编写访问OAuth服务的服务器的障碍。
这使上面的步骤1、2和5变得容易得多。
因此,在这一点上,我们的服务器具有一个永久访问令牌,该令牌是用户的用户名/密码。通过将访问令牌作为请求的一部分传递(作为查询参数,HTTP标头或POST表单数据),它可以代表用户向内容提供者发出请求。
如果仅通过SSL访问内容服务,那么我们就完成了。如果可以通过纯HTTP使用,则我们希望以某种方式保护该永久访问令牌。嗅探该连接的任何人都将永远能够访问该用户的内容。
OAuth 2解决的方法是使用刷新令牌。刷新令牌将成为等效的永久密码,并且仅通过SSL传输。当服务器需要访问内容服务时,它将刷新令牌交换为短暂的访问令牌。这样,所有可嗅探的HTTP访问都是使用将过期的令牌进行的。Google的OAuth 2 API使用的有效期为5分钟。
因此,除了刷新令牌之外,OAuth 2还简化了客户端,服务器和内容提供商之间的所有通信。并且仅当未加密访问内容时,刷新令牌才存在以提供安全性。
两足式身份验证
但是,有时服务器仅需要控制对其自身内容的访问。两足式身份验证允许客户端直接通过服务器对用户进行身份验证。
OAuth 2标准化了对OAuth 1的一些扩展,这些扩展已得到广泛使用。我最了解的一个是Twitter引入的xAuth。您可以在OAuth 2中将其视为“ 资源所有者密码凭据”。
本质上,如果您可以使用用户的凭据(用户名和密码)信任客户端,则他们可以直接与内容提供者交换这些凭据以获得访问令牌。这使OAuth在移动应用程序上更加有用-使用三足身份验证,您必须嵌入HTTP视图才能处理内容服务器的授权过程。
对于OAuth 1,这不是官方标准的一部分,并且需要与所有其他请求相同的签名过程。
我刚刚使用资源所有者密码凭证实现了OAuth 2的服务器端,从客户端的角度来看,获取访问令牌非常简单:从服务器请求访问令牌,将客户端ID /秘密作为HTTP授权标头传递,用户的登录名/密码作为表单数据。
优势:简单
因此,从实现者的角度来看,我在OAuth 2中看到的主要优点是降低了复杂性。它不需要请求签名过程,这不是很困难,但是肯定很麻烦。它极大地减少了充当服务客户所需的工作,而这正是您(最现代的移动世界)最希望减轻痛苦的地方。服务器->内容提供商端的复杂性降低,使其在数据中心中更具可伸缩性。
并且它把现在广泛使用的OAuth 1.0a扩展(例如xAuth)编入标准。