开放授权(OAuth, Open Authorization)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表等),而无需将用户名的密码提供给第三方应用。OAuth2.0是OAuth的2.0版本。本文主要介绍OAuth2的授权流程。
名词解释
- Resource Owner:资源拥有者
- Resource Server:资源服务器
- Client:客户端
- Authorization Server:认证服务器
- User Agent:用户代理,通常指浏览器
场景
在现实生活中就存在OAuth的场景:快递员给你送快递,但他进不了小区,他只能按下你家的门牌号,然后你通过摄像头确认他的确是给你来送快递的快递员,然后你给它解除门禁,快递员就能进入小区了给你送快递了。
在这个例子中,你就是资源拥有者(Resource Owner),小区内基础设施可以理解为资源(Resource),物业就是资源服务器(Resource Server),快递员是客户端(Client),门禁就是认证服务器(Authorization Server)。
你是受认证的业主,可以通过门禁卡、人脸认别等方式自由进入小区。但快递员不是业主,也想进入小区,怎么办呢?你可以直接把门禁卡给他,但这样不安全,所以门禁系统推出一个授权的功能,就是快递员先向你请求要进入小区,经过你的授权后再给他开门。如果你的快递比较多,这个快递员每天都要来送快递,每次都要你给他授权也比较麻烦,然后门禁系统又推出一个带有效期的临时出入卡,比如有效期一个周,那快速员就可以在这一个周之内自由出入小区了。
以上场景就是OAuth授权的原理,为了贴合互联网应用场景,OAuth制定了一套开放标准。
动机
在传统C/S认证模型中,客户端使用资源拥有者的认证凭证从资源服务器中访问资源。如果有一个第三方应用想要访问资源服务器中的受限资源,那么资源拥有者需要将其认证凭证分享给第三方应用,这带来了一些问题和限制:
- 第三方应用为了后续能够访问资源,需要存储资源拥有者的认证凭证,如密码等。
- 服务器需要支持密码身份验证,尽管密码本身存在安全缺陷。
- 第三方应用拥有资源拥有者的所有权限,资源拥有者也没办法限制,毕竟密码都告诉别人了。
- 资源拥有者修改密码后,所有第三方应用的权限均被收回。
- 任何一个第三方应用造成的密码泄漏会终端用户的密码和数据被泄露。
认证流程
OAuth的认证流程跟上述场景是类似的:
(A) 客户端向资源拥有者申请授权
(B)资源拥有者同意授权
(C)客户端使用上一步中拿到的授权凭证向认证服务器申请令牌
(D)认证服务器返回令牌
(E)客户端使用令牌向资源服务器获取资源
(F)资源服务器确认令牌有效后返回资源
上述6个步骤中,最关键的步骤就是(B),即资源拥有者向客户端授权的过程。
授权模式
授权是指资源拥有者同意客户端获取受限资源后,给予客户端认证的表现方式。OAuth有4种授权模式,分别是授权码模式(Authorization Code)、简化模式(Implicit)、密码模式(Resource Owner Password Credentials)以及客户端模式(Client Credentials)。
授权码模式
授权码模式是功能最完整、流程最严密的授权模式,也是使用最广泛的授权模式。它的特点就是通过客户端的后台服务器,与”服务提供商”的认证服务器进行交互。
由于授权码模式是基于页面跳转的流程,所以客户端需要跟用户代理(通常是web浏览器)交互。
(A)客户端(Client)通过用户代理(User-Agent)请求认证服务器(Authorization Server)。
(B)授权服务器验证用户是否给客户端授权。
(C)如果用户同意给客户端授权,认证服务器将会跳转到客户端事先指定的”重定向URI(redicreation URI)”同时附上一个授权码(authorization code)。
(D)客户端收到授权码,随上之前的重定向URI,向认证服务器申请令牌。这一步是在客户端的后台服务器上完成的,对用户不可见。
(E)认证服务器核对授权码和重定向URI,确认无误后,向客户端返回访问令牌(access token)和更新令牌(refresh token)。
简化模式
简化模式不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了”授权码”这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
同样,由于简化模式也是基于页面跳转的流程,所以客户端需要跟用户代理(通常是web浏览器)交互
(A)客户端通过用户代理请求认证服务器。
(B)授权服务器验证用户是否给客户端授权。
(C)如果用户同意给客户端授权,认证服务器将跳转至客户端指定的“重定向URI”,并在URI中的fragment中包含访问令牌(access token)。
(D)浏览器向资源服务器发出请求,但不包括上一步中收到的fragment部分的值。浏览器将在本地保留fragment中的信息。
(E)资源服务器返回一个页面,页面中一段可以提供fragment中的token的代码。
(F)浏览器执行上一步中资源服务器返回的代码,从fragment中提取出token。
(G)浏览器将令牌传给客户端。
密码模式
密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向认证服务提供商索要授权。密码模式适用于对客户端高度信任的场景。
(A)用户向客户端提供用户名和密码。
(B)客户端使用用户名和密码向认证服务器请求令牌。
(C)认证服务器确认无误后给客户端下发令牌。
客户端模式
客户端模式(client credentials grant)甚至都不需要用户授权,由客户端直接以用户的名义使用客户端凭证向认证服务器请求认证。
(A)客户端向认证服务器请求身份认证和获取令牌。
(B)认证服务器确认无误后向客户端下发令牌。
参考资料
[1] rfc6749
[2] OAuth Wiki
[3] 理解OAuth 2.0