OAuth协议源于OpenID,但是OpenID只用于校验用户身份,而OAuth为解决用户授权资源提供服务对第三方应用开放指定资源访问。2007年10月,OAuth1.0草案发布,2009年4月23日因OAuth1.0的3阶段OAuth认证流程漏洞,补充发布了OAuth1.0a版本,2010年4月OAuth2.0协议发布,与OAuth1.0不兼容,OAuth2相对与OAuth1,简化了签名逻辑,对桌面、移动应用做了优化。
相对于传统的CS模式,OAuth协议引入了一个新角色:资源所有者。这种角色在如今云服务及平台服务广为运用的环境下,出现得非常频繁,此时服务平台或云作为server,发起请求方作为Client,而服务平台或云的用户则是资源所有者,为Client的请求赋权。OAuth协议里,Server需要对资源所有者进行验证,也必须对Client的授权验证。这样,Client可以获得资源的访问授权,而资源所有者又不用将Server的用户名密码泄露给Client,同时还能对授权进行范围、时间的控制。
这里主要讨论OAuth协议最重要的两个版本的授权过程(OAuth1.0与OAuth1.0a授权过程无显著调整)。
现在定义如下角色:
- 受保护资源S —— 模拟情景中被授权访问的实体。
- 请求者A —— 第三方应用,请求S,大多数情况下,请求者也是一个CS系统,这里将其视为整体,不考虑其内部交互。
- 服务者B —— S存放载体,对外提供S的可控访问。
- 资源所有者C —— S的拥有者,同时也是B的用户。
其中C作为B的用户,可使用用户名密码登陆B,对S的访问进行操作、访问权限控制。
为了保护C的信息安全,A可获得对S的访问,同时不获取C的用户名密码。
OAuth1授权过程
1 | +----------+ +----------+ |
- A需要注册B获得访问域授权A,及授权范围,A需要配置调用的B的接口参数,使用HMAC-SHA1对参数进行签名。
- A申请Request temporary credentials:C最终会从A跳转请求B的鉴权系统来进行用户校验及授权,因此A需要从B获取一个Request temporary credentials,来对此请求进行校验,A访问B协定的Request Token Url接口,B返回A临时证书,此证书并未获得C授权。
- C访问Auth接口:A使用临时证书,请求B的授权地址,来对C进行身份验证,请求授权地址时B会根据临时证书,获取并告知C所需要授予的权限,C使用账号密码进行验证,从而完成授权,B生成Auth Token,使用此Token回调A,得到C授权。
- A访问Access接口:A使用Auth Token请求B的Request Access Url,B生成Access Token返回给A。
- 请求S:A使用Access Token请求S。
最初的OAuth1.0过程存在漏洞,如果将这一过程看作一个session,这个漏洞允许攻击者劫持用户的session,具体过程为,攻击者初始化一个合法Request temporary credentials,让C进行授权,篡改回调地址,从而拿到C的Auth Token授权,实现资源的盗取访问。OAuth1.0a针对性的修复了这一问题,协议要求,A在申请Request temporary credentials时,传递oauth_callback,来确定Auth token的回调地址,而不是在Auth token请求中,从而攻击者无法假冒回调,而B在回调返回Auth token时,同时会返回oauth verifier,用于验证A向B发出的Access token请求,只可使用一次来防止重放。
OAuth2授权过程
OAuth2协议与OAuth1大相径庭,OAuth2也不向下兼容,相比OAuth1,OAuth2将Server进一步划分成Resource Server和Auth Server两种角色,负责S的鉴权和授权。
在进行授权之前,OAuth2也需要A向B进行注册,但协议不规定注册方式,注册需要表明A的类型(Client的类型),提供A的重定向地址(用于用户授权后回调),其他A的信息(如应用名,网站域名,描述等)。
Client可以分为两种:公开客户端及保密客户端,区别在于客户端是否有维护证书安全的能力,可以适应桌面系统,CS架构,BS架构等多种环境下的鉴权验证。
注册之后Auth Server会给A分发一个Client ID,在Auth Server端,此编号唯一,用于确定Client的身份。保密客户端同时会获得一个密码或密钥对,用于向Auth Server验证自己的身份,而公开客户端需要确定与Auth Server的校验方法。
授权过程为
1 | +--------+ +---------------+ |
- (A)过程,请求者向用户请求授权,或由Authorization Server作为中介请求授权。
- (B)过程,请求者从被请求方获得授权,取得授权的方式,由请求方所请求的方式及被请求方实现确定。
- (C)过程,请求者使用(B)过程取得的授权向Authorization Server请求资源访问token。
- (D)过程,授权验证方对授权进行验证,发放访问token,token具有有效期。
- (E)过程,请求者使用token访问Resource Server托管的资源。
- (F)过程,Resource验证token的有效性,返回所请求的资源。
具体实现中,由于授权(Authorization Grant)方式的的不同,又分为authorization code,implicit,resource owner password credentials,client credentials,同时保留扩展授权定义。
Authorization code
1 | +----------+ |
Authorization Code为有证书客户端的首选方案,其基于重定向的授权方式,要求Client具有维护证书能力,且与标准用户接口存在交互,可接收从Authorization Server产生的authorization code重定向,BS架构的应用是非常典型的运用场景。
Access token一般都有较短的失效时间,Authorization Server在响应Auth token的时候可选返回一个时间稍微长一些的Refresh token来,当Access Token失效后使用Refresh Token重新获取。
Implicit Grant
1 | +----------+ |
implicits授权使用在公开Client环境下,相比Authoriation code的授权,implicit授权没有Auth token换取Access token过程,也无法使用Refresh token刷新Access Token。
Resource Owner Password Credentials
1 | +----------+ |
此授权方式要求Client必须是资源所有者可信环境,比如操作系统或具有高权限的应用以及内网环境鉴权。
Client Credentials Grant
1 | +---------+ +---------------+ |
仅可用于保密客户端,资源所有者预先向Authorization Server声明了Client的权限或访问Client控制范围内的受保护数据。
OAuth1与OAuth2的不同点
- OAuth2的在非BS的服务体系下更友好,对于授权过程,根据使用环境,有多种策略,而OAuth1只能引导客户打开浏览器或调用非操作系统非常规接口来进行身份验证及Token验证(如查询操作系统打开窗口名称验证OAuth Verifier)
- OAuth1需要对参数进行签名,需要进行参数排序等复杂过程,而OAuth2使用https过程更简单。
- OAuth2对于资源托管方的角色分解更直观。
- OAuth2令牌有有效期,相比OAuth1,权限控制更得当。