OAuth是一个关于授权的开放网络标准,在世界范围内被广泛使用。当前版本是2.0版本。本文简要说明了OAuth 2.0的设计思想和操作流程,主要参考资料为RFC 6749。
首先,应用场景
为了了解OAuth的适用情况,我举一个假设的例子。有一个“云打印”网站,可以打印用户在谷歌存储的照片。为了使用这项服务,用户必须让云打印阅读他们存储在谷歌上的照片。
问题是谷歌只会允许‘云打印’在用户授权下阅读这些照片。那么,‘云打印’是如何获得用户授权的呢?
传统上,用户告诉“云打印”他们的谷歌用户名和密码,后者可以读取他们的照片。这种方法有以下严重缺点。
(1)‘云打印’会保存用户密码用于后续服务,非常不安全。(2)谷歌要部署密码登录,我们知道简单的密码登录是不安全的。(3)“云打印”有权获取用户在谷歌存储的所有数据,用户不能限制“云打印”的授权范围和有效性。(4)用户只有通过更改密码才能收回赋予‘云打印’的权力。但是这样做会使用户授权的所有其他第三方应用程序失效。(5)只要第三方应用被破解,就会导致用户密码和所有受密码保护的数据泄露。
OAuth就是为了解决这些问题而诞生的。
二、名词的定义
在详细解释OAuth 2.0之前,我们需要了解一些特殊的术语。他们对理解下面的解释非常重要,尤其是几张图片。
(1)第三方应用:第三方应用,本文也称之为“客户端”,即上一节示例中的“云打印”。(2) HttpService: HTTP服务提供者,在本文中被称为‘服务提供者’,也就是前面例子中的Google。(3)资源所有者:资源所有者,本文也称“用户”。(4)用户代理:User Agent,在本文中是浏览器的意思。(5)授权服务器:认证服务器,即服务提供者专门用来处理认证的服务器。(6)资源服务器:资源服务器,即服务提供商存储用户生成的资源的服务器。它可以是相同的服务器,也可以不同于身份验证服务器。
了解了这些名词,就不难理解,OAuth的功能是让“客户端”能够安全可控地从“用户”那里获得授权,并与“服务提供者”进行交互。
第三,OAuth的思维
OAuth在“客户端”和“服务提供商”之间设置授权层。客户端不能直接登录服务商,只能登录授权层,以区别用户和客户端。“客户端”用来登录授权层的令牌不同于用户的密码。登录时,用户可以指定授权层令牌的权限范围和有效期。
“客户端”登录授权层后,“服务提供者”根据令牌的权限范围和有效期将用户存储的数据打开给“客户端”。
四.操作过程
OAuth 2.0的流程图如下,取自RFC 6749。
(a)用户打开客户端后,客户端向用户请求授权。用户同意授权客户。(c)客户端使用上一步中获得的授权向认证服务器申请令牌。(d)认证服务器对客户端进行认证后,确认其正确并同意发放令牌。(e)客户端使用令牌向资源服务器申请获取资源。(f)资源服务器确认令牌是正确的,并同意向客户端打开资源。
不难看出,在以上六个步骤中,B是关键,即用户如何对客户端进行授权。有了这个授权,客户端就可以获得令牌,然后通过令牌获得资源。下面解释客户端获取授权的四种模式。
动词(verb的缩写)客户授权模式
客户端必须是授权用户才能获得访问令牌。OAuth 2.0定义了四种授权方法。
1.授权码)2。含蓄)3。资源所有者密码凭证4。客户端凭据
不及物动词授权码模式
授权码是功能最全、流程最严格的授权方式。其特点是通过客户端的后台服务器与‘服务提供商’的认证服务器进行交互。
它包括以下步骤:
(a)用户访问客户端,后者将前者导向认证服务器。(b)用户选择是否向客户端授予授权。(c)假设用户给予授权,认证服务器将用户指引到客户端预先指定的URI(重定向URI),同时附加授权码。(d)客户端接收授权码,附加先前的“重定向URI”,并向认证服务器申请令牌。这一步是在客户端后台的服务器上完成的,用户看不到。(e)认证服务器检查授权码和重定向URI,并向客户端发送访问令牌和刷新令牌。
上述步骤需要以下参数。
在步骤a中,客户端申请认证的URI包含以下参数:
1.response_type:指示授权类型,必选,其中值固定为“code”。2.client _ ID:表示客户端的ID,必选3.redirect_URI:表示重定向URI,可选4.scope:表示请求的权限范围,可选5.state:表示客户端的当前状态,可以指定任何值,认证服务器将原封不动地返回。以下是一个例子。
复制代码如下:GET /authorize?response _ type=code client _ id=s6bhdrkqt3s state=XYZ redirect _ uri=https://client . example.com/CB HTTP/1.1 host : server.example.com
在步骤c中,服务器响应客户端的URI,包括以下参数:
1.code:表示授权码,必选。该代码的有效期应该很短,通常设置为10分钟,客户端只能使用该代码一次,否则会被授权服务器拒绝。该代码与客户端标识和重定向URI一一对应。2 .状态:如果这个参数包含在客户端的请求中,那么认证服务器的响应也必须准确地包含这个参数。
以下是一个例子。复制代码如下: http/1.1 302找到位置3360 https://client.example.com/cb?代码=SplxlOBeZQQYbYS6WxSbIA状态=xyz
在步骤d中,客户端向认证服务器申请令牌的HTTP请求,该请求包括以下参数:1.grant_type:表示使用的授权模式,必选,这里的值固定为‘authorization _ code’。2.code:表示上一步获得的授权码,必选。3.redirect_URI:指示重定向URI,这是必需的,并且必须与步骤a中的参数值一致。
以下是一个例子。
复制代码如下: post/token http/1.1host 3360 server . example.com authorization : basic czzgagrs 3f 0 mzpnwdfmqmf 0 m2jw content-type : application/x-www-form-URL encoded
grant _ type=authorization _ code code=splxlobzqqqybys6 wxsbiaredirect _ uri=https://client . example.com/CB
在步骤e中,认证服务器发送的HTTP回复包含以下参数:
1.access_token:指示所需的访问令牌。2.token_type:指示标记类型,不区分大小写。必选,可以是承载类型或mac类型。3.expires_in:以秒为单位指示到期时间。如果省略此参数,则必须以其他方式设置到期时间。4.refresh_token:指示更新令牌,用于获取下一个访问令牌,可选。5 .范围:表示权限范围。如果与客户申请的范围一致,可以省略此项。以下是一个例子。
复制代码如下: http/1.1 200 ok内容类型:应用/JSON;charset=UTF-8缓存-控制:无存储Pragma:无缓存
{ ' access _ token ' : ' 2yotnfzfejr1zsicmwpaa ',' token_type':'example ',' expires_in':3600,' refresh _ token ' : ' tgzv3jokf0x g5qx2tlkwia ',' example _ parameter ' : ' example _ value ' }
从上面的代码可以看出,相关参数是以JSON格式发送的(content-type : application/JSON)。此外,HTTP头信息明确指定不应该缓存它。
七、简化模型
隐式授权类型直接从浏览器中的身份验证服务器申请令牌,而不经过第三方应用程序的服务器,并跳过“授权码”这一步骤,因此得名。所有步骤都在浏览器中完成,令牌对访问者可见,客户端不需要身份验证。
它包括以下步骤:
(a)客户端将用户导向认证服务器。(b)用户决定是否向客户端授予授权。(c)假设用户给予授权,认证服务器将用户定向到客户端指定的“重定向URI”,并将访问令牌包含在URI的哈希部分。(d)浏览器向资源服务器发送请求,该请求不包括上一步骤中接收的哈希值。(e)资源服务器返回网页,网页中包含的代码可以获取Hash值中的令牌。(f)浏览器执行上一步获得的脚本并提取令牌。(g)浏览器将令牌发送给客户端。
上述步骤需要以下参数。在步骤a中,客户端发送的HTTP请求包括以下参数:
1.response_type:表示授权类型,这里的值固定为‘token’,这是必需的。2.client_id:表示客户端的ID;必需的。3.redirect_uri: URI表示重定向,可选。4.scope:表示权限范围,可选。5.state:指示客户端的当前状态。可以指定任何值,身份验证服务器将完整地返回该值。
以下是一个例子。
复制代码如下:GET /authorize?response _ type=token client _ id=s6bhdrkqt3s state=XYZ redirect _ uri=https://client . example.com/CB HTTP/1.1 host : server.example.com
在步骤c中,认证服务器响应客户端的URI,包括以下参数:
1.access_token:指示所需的访问令牌。2.token_type:指示令牌类型,不区分大小写,是必需的。3.expires_in:以秒为单位指示到期时间。如果省略此参数,则必须以其他方式设置到期时间。4 .范围:表示权限范围。如果与客户申请的范围一致,可以省略此项。5 .状态:如果这个参数包含在客户端的请求中,那么认证服务器的响应也必须准确地包含这个参数。
以下是一个例子。复制代码如下: http/1.1 302找到位置3360 http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA状态=XYZ token _ type=example expires _ in=3600
在上例中,认证服务器使用HTTP头信息的Location列来指定浏览器重定向的URL。请注意,该网址的哈希部分包含令牌。
根据上面的步骤d,浏览器将在下一步访问Location指定的URL,但不会发送Hash部分。在下一步e中,服务提供商的资源服务器发送的代码将提取Hash中的令牌。
八、密码模式
在密码模式(资源所有者密码凭据授予)下,用户向客户端提供自己的用户名和密码。客户使用这些信息向“服务提供商”请求授权。
在这种模式下,用户必须将其密码提供给客户端,但客户端不得存储密码。这通常在用户对客户端具有高度信任时使用,例如,客户端是操作系统的一部分或由著名公司生产。但是,只有在无法实现其他授权模式的情况下,身份验证服务器才能考虑使用此模式。
它包括以下步骤:
(a)用户向客户端提供用户名和密码。(b)客户端向认证服务器发送用户名和密码,并向认证服务器请求令牌。(c)认证服务器确认无误后,向客户端提供访问令牌。
在步骤b中,客户端发送的HTTP请求包括以下参数:
1.grant_type:表示授权类型。这里的值固定为“密码”,这是必需的。2.username:表示用户名,必选。3.password:表示用户的密码,必选。4.scope:表示权限范围,可选。
以下是一个例子。复制了以下代码: post/token http/1.1 host 3360 server.example.com的授权: basic czzcagsars 3f 0mzpnwdfmqmf 0 m2 jw content-type 3360 application/x-www-form-URL encoded。
grant _ type=password username=John doe password=a3 ddj3wc在步骤中,身份验证服务器向客户端发送访问令牌。下面是一个例子。复制的代码如下: http/1.1 200 ok内容类型:应用/JSON;charset=UTF-8缓存-控制:无存储Pragma:无缓存
{ ' access _ token ' : ' 2yotnfzfejr1zsicmwpaa ',' token_type':'example ',' expires_in':3600,' refresh _ token ' : ' tgzv3jokf0x g5qx2tlkwia ',' example _ parameter ' : ' example _ value ' }
在上述代码中,每个参数的含义参见第《授权码模式》节。在整个过程中,客户端不得保存用户密码。
九.客户端模式。
客户端凭据授权意味着客户端以自己的名称向“服务提供商”进行身份验证,而不是以用户的名义。严格来说,客户端模式不是OAuth框架要解决的问题。在这种模式下,用户直接向客户端注册,客户端请求“服务提供商”以自己的名义提供服务。其实不存在授权问题。
它包括以下步骤:
(a)客户端对认证服务器执行身份认证,并需要访问令牌。(b)认证服务器确认无误后,向客户端提供访问令牌。
在步骤a中,客户端发送的HTTP请求包括以下参数:
1.granttype:指示授权类型。这里的值固定为“clientcredentials ”,这是必需的。2 .范围:表示权限范围,可选。
复制了以下代码: post/token http/1.1 host 3360 server.example.com的授权: basic czzcagsar 3f 0 mzpnwdfmqmf 0 m2jw内容-type 3360 application/x-www-form-URL encoded
grant _ type=client _凭据
身份验证服务器必须以某种方式验证客户端的身份。在步骤b中,认证服务器向客户端发送访问令牌。以下是一个例子。
复制代码如下: http/1.1 200 ok内容类型:应用/JSON;charset=UTF-8缓存-控制:无存储Pragma:无缓存
{ ' access _ token ' : ' 2yotnfzfejr1zsicmwpaa ',' token_type':'example ',' expires_in':3600,' example _ parameter ' : ' example _ value ' }
在上述代码中,每个参数的含义参见第《授权码模式》节。
X.更新令牌
如果用户访问时客户端的“访问令牌”已过期,则需要使用“更新令牌”申请新的访问令牌。
客户端发送更新令牌的HTTP请求,该请求包含以下参数:1.granttype:指示使用的授权模式,其中值固定为“refreshtoken”,这是必需的。2.refresh_token:表示之前收到的更新令牌;必需的。3 .范围:表示应用程序的授权范围,不能超出上一个应用程序的范围。如果省略此参数,则意味着它与之前的应用程序一致。
以下是一个例子。
复制了以下代码: post/token http/1.1 host 3360 server.example.com的授权: basic czzcagsar 3f 0 mzpnwdfmqmf 0 m2jw内容-type 3360 application/x-www-form-URL encoded
grant _ type=refresh _ token refresh _ token=tgzv3jokf0x g5qx2tlkwia
(结束)