背景:我已经为OAuth 1.0a和2.0编写了客户端和服务器堆栈。
OAuth 1.0a和2.0都支持两条腿的身份验证,其中服务器可以确保用户的身份;三条腿的身份验证,其中内容提供者可以确保服务器可以提供用户的身份。授权请求和访问令牌在三脚身份验证中发挥作用,重要的是要注意OAuth 1也具有这些功能。
复杂的是:三条腿的身份验证
OAuth规范的一个要点是内容提供者(例如Facebook、Twitter等)向服务器(例如希望代表客户端与内容提供者对话的Web应用程序)保证客户端具有某种身份。三脚身份验证所提供的能力是,客户端或服务器不需要知道身份的详细信息(例如用户名和密码)。
没有(?)深入了解OAuth的细节:
The client submits an authorization request to the server, which validates that the client is a legitimate client of its service.
The server redirects the client to the content provider to request access to its resources.
The content provider validates the user's identity, and often requests their permission to access the resources.
The content provider redirects the client back to the server, notifying it of success or failure. This request includes an authorization code on success.
The server makes an out-of-band request to the content provider and exchanges the authorization code for an access token.
服务器现在可以通过传递访问令牌来代表用户向内容提供者发出请求。
每个交换(客户端->服务器,服务器->内容提供程序)都包含对共享秘密的验证,但由于OAuth 1可以在未加密的连接上运行,因此每个验证不能通过线路传递秘密。
正如您所注意到的,HMAC已经做到了这一点。客户端使用它与服务器共享的秘密对其授权请求的参数进行签名。服务器获取参数,自己用客户端的密钥为其签名,并能够查看它是否是一个合法的客户端(在上面的第1步中)。
这个签名要求客户端和服务器双方就参数的顺序达成一致(因此它们签署的是完全相同的字符串),关于OAuth 1的主要抱怨之一是它要求服务器和客户端都进行相同的排序和签名。这是精细的代码,要么它是正确的,要么你得到401未经授权的帮助。这增加了编写客户机的障碍。
通过要求授权请求在SSL上运行,OAuth 2.0完全消除了参数排序和签名的需要。客户端将其秘密传递给服务器,服务器直接对其进行验证。
同样的要求也出现在服务器->内容提供程序连接中,由于这是SSL,因此消除了编写访问OAuth服务的服务器的一个障碍。
这让上面的步骤1、2和5变得容易多了。
所以在这一点上,我们的服务器有一个永久的访问令牌,它是用户的用户名/密码等效。它可以通过将访问令牌作为请求的一部分(作为查询参数、HTTP报头或POST表单数据)传递,代表用户向内容提供者发出请求。
如果内容服务只能通过SSL访问,我们就完成了。如果它可以通过纯HTTP获得,我们希望以某种方式保护永久访问令牌。任何嗅探到连接的人都能够永远访问用户的内容。
在OAuth 2中解决这个问题的方法是使用一个刷新令牌。刷新令牌成为永久的密码等效物,并且它只通过SSL传输。当服务器需要访问内容服务时,它将刷新令牌交换为短期访问令牌。这样,所有可嗅探的HTTP访问都使用一个将过期的令牌进行。谷歌在他们的OAuth 2 api上使用了5分钟的过期时间。
因此,除了刷新令牌之外,OAuth 2简化了客户机、服务器和内容提供者之间的所有通信。刷新令牌的存在只是为了在未加密的情况下访问内容时提供安全性。
两条腿的身份验证
但是,有时服务器只需要控制对自己内容的访问。两腿身份验证允许客户端直接使用服务器对用户进行身份验证。
OAuth 2标准化了一些广泛使用的OAuth 1扩展。我最熟悉的是Twitter上介绍的xAuth。您可以在OAuth 2中看到它作为资源所有者密码凭据。
从本质上讲,如果您可以信任客户端拥有用户的凭据(用户名和密码),客户端就可以直接与内容提供者交换访问令牌。这使得OAuth在移动应用程序上更有用——使用三脚身份验证,您必须嵌入一个HTTP视图,以便处理内容服务器的授权过程。
对于OAuth 1,这不是官方标准的一部分,并且需要与所有其他请求相同的签名程序。
我刚刚用资源所有者密码凭据实现了OAuth 2的服务器端,从客户端角度来看,获取访问令牌变得很简单:从服务器请求一个访问令牌,将客户端id/secret作为HTTP授权标头传递,并将用户的登录/密码作为表单数据传递。
优点:简单
因此,从实现者的角度来看,我在OAuth 2中看到的主要优势是降低了复杂性。它不需要请求签名过程,这个过程并不难,但确实很繁琐。它极大地减少了充当服务客户端所需的工作,这正是(在现代移动世界中)您最想要最小化痛苦的地方。服务器->内容提供程序端复杂性的降低使其在数据中心更具可伸缩性。
它还将一些目前广泛使用的OAuth 1.0a扩展(如xAuth)编入标准。