前言
OAuth2.0
授权框架让第三方应用获得了
HTTP
服务商的受限许可,要么通过组织在资源拥有者和
HTTP
服务商之间的被批准的交互动作代表用户,要么允许第三方应用代表用户获得访问的权限,这个说明书完全替代了之前过时的
OAuth1.0
协议的版本
目录
<!–[if !supportLists]–>
1
<!–[endif]–>
介绍
(Introduction)
在传统的客户端
–
服务端认证模型中,客户端请求一个在服务器中许可受限的资源
(
受保护的资源
)
时,是
使用的资源所有者的
身份凭证与服务器进行验证
.
为了给第三方应用提供受限资源的访问权限,资源的拥有者可以与它分享他的身份凭证。但是这出现了一些问题和限制:
第三方应用需要储存资源拥有者的身份凭证以供将来使用,通常又是以一个明文方式
(
某网站明文加密
)
服务商需要支持密码验证,尽管密码存在固有的安全漏洞
(SB
密码大量存在
)
第三方应用程序获得过于广泛的访问资源拥有者的受保护资源的权限
,
让资源所有者没有任何能力限制持续时间或访问受限的子资源的权限。
(
某些网站无法无天的利用用户的资源
)
资源拥有者不能单独撤销一个第三方的访问权限而不影响其余的第三方,如果一定要这样做,只能通过修改第三方的密码
(
牵一发动全身,有的允许,有的拒绝
)
任何第三方应用收到危害都将导致最终用户的密码和所有被该密码保护的数据面临危害
(
某网站被攻击了,难道我们也要跟着倒霉?
)
Oauth
通过引入授权层和从资源拥有者分离客户端角色来为这些问题定址。在
Oauth
协议中,客户端需要访问被资源拥有者控制的在资源服务器存储的资源,并且被发行一组不同的身份凭证,比资源拥有者的凭证还多。
为了替代直接使用资源拥有者的身份凭证去访问被保护的资源,客户端获得了一个
access_token
,它是一个字符串表示一个特点的范围,生命周期,和其他准入属性。
Access_tokens
通过授权服务器获得资源拥有者许可后被发布给第三方客户端。客户端使用
access_token
去访问存储在资源服务器上的被保护的资源。
譬如,一个
end-user(
资源拥有者
)
可以授予一个打印服务商
(
客户端
)
去访问她存储在图片分享服务端
(
资源服务器
)
的加密图片
.
相反,她直接授权给一个被图片分享网站
(
授权服务器
)
信任的服务,这个网站给这个打印服务特殊的授权凭证
(access_token)
这个规格书为使用
HTTP
服务而设计。
OAuth
除了用在
HTTP
协议上,在其他任何协议上使用都是超出了范围。
Oauth1.0
协议,作为一个信息文档发行,曾经是一个小的特别设计努力的结果。这个标准形成规范的文档是建立在
Oauth1.0
开发经验基础之上的,以及
来自更广泛的
IETF
社区
额外的用例和可扩展性
需求。
Oauth2.0
协议不向后兼容
Oauth1.0
。这两个版本可能共存在网上,具体的实现也可能两者都支持。然而,该规格书的意图是本文档中指定的新实现方法只支持
Oauth2.0
,
OAuth1.0
只用于支持现存的项目。
Oauth2.0
协议分享很少的关于
Oauth1.0
的实现方法的详情。熟悉
Oauth1.0
协议的开发这应该多参考没有任何假设
,
结构和细节的文档。
<!–[if !supportLists]–>1.1<!–[endif]–>
角色
(Roles)
Oauth
定义了四个角色
资源拥有者:
一个有授予访问受保护资源权限能力的实体。当这个资源拥有者是一个人时,通常被称为终端用户
资源服务器
这个服务器保存了受保护的资源,通过使用
access_token
请求能接收并返回受保护的资源
客户端
一个使用受保护资源的客户端请求代表资源拥有者,获得它的授权。这个术语
”
客户端
”
不意味任何特殊的实现特性
(
即无论这个应用是服务器执行,还是在桌面,或者其他设备上
)
。
授权服务器
这个服务器在成功验证资源拥有者并获取授权后给客户端发行
access_tokens
在授权服务器和资源服务器之间的交互超过了该规格书的说明。这个授权服务器可能和资源服务器可能是一个服务器,也可以分开。一个单独的授权服务器可以发现被多种资源服务器接受的
access_tokens
。
<!–[if !supportLists]–>1.2<!–[endif]–>
协议流
(Protocol Flow)
+———+ +—————-+
| |—-(A)- Authorization Request -> | Resource |
| | | Owner |
| |<-(B)– Authorization Grant —-
| |
| | +—————-+
| |
| | +—————-+
| |—-(C)– Authorization Grant –> | Authorization |
| Client | | Server |
| |<-(D)—– Access Token ——- | |
| | +—————-+
| |
| | +—————-+
| |—-(E)—– Access Token ——> | Resource |
| | | Server |
| |<-(F)— Protected Resource —– | |
+———+ +—————-+
图形
1
:协议流摘要
在插图
1
中
OAuth2.0
协议流摘要描述的四个角色之间交互动作如下概述:
<!–[if !supportLists]–>
(A)
<!–[endif]–>
客户端向资源拥有者请求授权。这个授权请求可以被设计成直接指向资源拥有者
(
如图
),
最好还是间接通过授权服务器作为中介。
(
直接告诉用户,诶,把淘宝网的账户给我用下呗。这么做肯定不合适吧!所有一般是通过淘宝的授权服务器去给用户一个弹出框。这活,腾讯喜欢干
)
<!–[if !supportLists]–>
(B)
<!–[endif]–>
客户端收到授权批准,它代表资源拥有者授权的凭证,使用该规格书中定义的四个批准类型中的一个,或者是一个延伸的批准类型。这个授权批准类型依靠客户端请求验证使用的方法和授权服务器支持类型。
(
用户同意用
QQ
授权给这个应用,一般就把微博给他,好友列表给他啊等等,
MD
,信息就这么不要钱的给出去了。批准方法现在不多说
)
<!–[if !supportLists]–>
(C)
<!–[endif]–>
客户端通过验证授权服务器和提供授权批准方法来请求一个
access_token
。
(
其实每个授权批准方法都会有返回值,现在感觉用得好复杂
)
<!–[if !supportLists]–>
(D)
<!–[endif]–>
授权服务器鉴定客户端和确认这个授权批准,如果合法,发放
access_token
。
(
如何鉴定的,这才是最重要的吧!
)
<!–[if !supportLists]–>
(E)
<!–[endif]–>
客户端通过提供
access_token
从资源服务器请求受保护的资源和认证
(
确实很绕,又是认证,又是授权,又是批准
)
<!–[if !supportLists]–>
(F)
<!–[endif]–>
资源服务器确认
access_token,
如果合法就服务它的请求。
客户端从资源拥有者获取授权批准
(
见图中
A,B
的步骤
)
的首选方法是把授权服务器作为一个中介,具体可以去见图形
3 Section 4.1
。
<!–[if !supportLists]–>
1.3
<!–[endif]–>
授权批准
(Authorization Grant)
一个授权批准其实就是一个凭证,它代表着资源拥有者的授权
(
访问受保护资源的权限
)
被客户端用于获得
access_token
。这个规格书定义了四种批准的类型——授权码
(Authorization code)
,隐式
(Implicit)
,资源拥有者密码凭证
(resource owner password credentials)
,和客户端凭证
(client credentials)
,也有可拓展的机制来定义额外的类型。
<!–[if !supportLists]–>
1.3.1
<!–[endif]–>
授权码
(Authorization code)
授权码是通过使用作为客户端和资源拥有者间的中介授权服务器发放的。避免之前向资源拥有者请求授权,客户端尽量把资源拥有者引导到验证服务器
(
经由用户代理在
RFC2616
文中有定义
)
,验证服务器
引导用户携带授权码返回到客户端。
在引导用户携带授权码返回到客户端之前,验证服务器鉴定资源拥有者的正确性,并记录他的授权。因为资源拥有者仅仅和授权服务器进行鉴定,所有资源拥有者不会和客户端分享他的身份凭证
授权码提供少量的重要安全利益,例如鉴定客户端的能力,以及直接传送
access_token
给客户端,却不用通过资源拥有者的用户代理的许可,而且还有可能暴露给其他人,包括资源拥有者。
<!–[if !supportLists]–>
1.3.2
<!–[endif]–>
隐式
(Implicit)
隐式批准是简化后的授权码流程,尽量帮助客户端在浏览器通过脚本语言的方式实
现,譬如
JavaScript
。在隐式流中,避免发行授权码给客户端,而是直接给客户
access_token(
资源拥有者授权后的直接结果
)
。这种批准类型叫隐式,没有发行中介凭证
(
譬如一个授权码,授权码一般用于获取
access_token)
在隐式批准留着发行一个
access_token
,这个验证服务器是没有验证这个客户端的。在一些案例中,客户端的身份标识可以通过重定向
URI(
通常用于传送
access_token
给客户端
)
的方法进行验证。
Access_token
可以曝光资源拥有者或那些可以访问资源拥有者的应用的用户代理。
隐式批准提高了一些客户端的响应速度和处理效率
(
譬如那些网页嵌入应用的实现
)
,是因为它减少获取
access_token
的往返次数。而然,这种使用隐式批准的应用带来的便利应该权衡下它的安全性。譬如我们在
Section 10.3
和
10.16
中描述的例子,尤其当授权码批准方法可以使用的时候
<!–[if !supportLists]–>
1.3.3
<!–[endif]–>
资源拥有者密码凭证
(resource owner password credentials)
资源拥有者的密码凭证
(
也就是说,用户名和密码
)
可以直接用来当做授权批准去获得
access_token
。这种凭证只能用在客户端和资源拥有者有很高的信任级别的场景中
(
例如,客户端是设备操作系统的一部分,或者是享有特权较高的应用
)
,并且是在其他授权批准类型不可用的情况下。
尽管这种批准类型需要客户端访问资源拥有者的直接凭证,但是资源拥有者的凭证只能被一个请求所用,并且只能换一个
access_token
。这个批准类型可以消除客户端储存资源拥有者凭证以便以后使用的需求,通过用长久
access_token
或
refresh_token
交换凭证的方式。
<!–[if !supportLists]–>
1.3.4
<!–[endif]–>
客户端凭证
(client credentials)
客户端凭证
(
或者是其他客户端鉴定的形式
)
可以被用作授权批准的方式,如下情况,
授权范围被限制在客户端控制下的,或者是之前被授权服务器安排的受保护的资源。
客户端凭证批准方式在客户端就是资源拥有者,或者基于授权服务器之前安排的授权请求访问受限资源的情况下
被用作典型的授权批准类型