OAuth2.0深入理解

OAuth简介

A)客户端到授权服务器请求一个授权令牌(request token&secret)
B)引导用户到授权服务器请求授权
C)用访问令牌到授权服务器换取访问令牌(access token&secret)
D)用访问令牌去访问得到授权的资源
A)引导用户到授权服务器,请求用户授权,用户授权后返回 授权码(Authorization Code)
B)客户端由授权码到授权服务器换取访问令牌(access token)
C)用访问令牌去访问得到授权的资源
a)授权码
b)客户端私有证书
c)资源拥有者密码证书
d)刷新令牌
e)断言证书

OAuth 认证的流程

详细流程

OAuth协议案例描述

协议的参与者,OAuth 的参与实体至少有如下三个:

此外,为了支持开放授权功能以及更好地描述开放授权协议,OAuth 引入了第四个参与实体:

授权类型

在开放授权中,第三方应用 (Client) 可能是一个 Web 站点,也可能是在浏览器中运行的一段 JavaScript 代码,还可能是安装在本地的一个应用程序。这些第三方应用都有各自的安全特性。对于 Web 站点来说,它与 RO 浏览器是分离的,它可以自己保存协议中的敏感数据,这些密钥可以不暴露给 RO;对于 JavaScript 代码和本地安全的应用程序来说,它本来就运行在 RO 的浏览器中,RO 是可以访问到 Client 在协议中的敏感数据。

OAuth 为了支持这些不同类型的第三方应用,提出了多种授权类型,如:

其中最核心、最难理解、也是最广泛使用的一种授权类型为 “授权码”。

授权码类型的开放授权协议的流程

  1. Client 初始化协议的执行流程。首先通过 HTTP 302 来重定向 RO 用户代理到 AS。Client 在 redirect_uri 中应包含如下参数:client_id,scope (描述被访问的资源),redirect_uri (即 Client 的 URI),state (用于抵制 CSRF 攻击)。此外,请求中还可以包含 access_type 和 approval_prompt 参数。当 approval_prompt=force 时,AS 将提供交互页面,要求 RO 必须显式地批准 (或拒绝) Client 的此次请求。如果没有 approval_prompt 参数,则默认为 RO 批准此次请求。当 access_type=offline 时,AS 将在颁发 access_token 时,同时还会颁发一个 refresh_token。因为 access_token 的有效期较短 (如 3600 秒),为了优化协议执行流程,offline 方式将允许 Client 直接持 refresh_token 来换取一个新的 access_token。
  2. AS 认证 RO 身份,并提供页面供 RO 决定是否批准或拒绝 Client 的此次请求 (当 approval_prompt=force 时)。
  3. 若请求被批准,AS 使用步骤 1 中 Client 提供的 redirect_uri 重定向 RO 用户代理到 Client。redirect_uri 须包含 authorization_code,以及步骤 1 中 Client 提供的 state。若请求被拒绝,AS 将通过 redirect_uri 返回相应的错误信息。
  4. Client 拿 authorization_code 去访问 AS 以交换所需的 access_token。Client 请求信息中应包含用于认证 Client 身份所需的认证数据,以及上一步请求 authorization_code 时所用的 redirect_uri。
  5. AS 在收到 authorization_code 时需要验证 Client 的身份,并验证收到的 redirect_uri 与第 3 步请求 authorization_code 时所使用的 redirect_uri 相匹配。如果验证通过,AS 将返回 access_token,以及 refresh_token (若 access_type=offline)。

步骤 4 中,Client 需要拿 “授权码” 去换 “授权令牌” 时,Client 需要向 AS 证明自己的身份,即证明自己就是步骤 2 中 Alice 批准授权时的 Grantee。这个身份证明的方法主要有两种:

  1. 通过 https 直接将 client_secret 发送给 AS,因为 client_secret 是由 Client 与 AS 所共享,所以只要传送 client_secret 的信道安全即可。(利用TSL安全信道传送client_secret验证身份)
  2. 通过消息认证码来认证 Client 身份,典型的算法有 HMAC-SHA1。在这种方式下,Client 无需传送 client_secret,只需发送消息请求的 signature 即可。由于不需要向 AS 传递敏感数据,所以它只需要使用 http 即可。(利用client与AS共享的client_cecret与消息的绑定的hash签名值验证身份)

此外,在步骤 2 中,Google 授权服务器需要认证 Alice 的 RO 身份,并提供授权界面给 Alice 进行授权审批。

为何引入 authorization_code

协议设计中,为什么要使用 authorization_code 来交换 access_token?这是读者容易想到的一个问题。也就是说,在协议的第 3 步,为什么不直接将 access_token 通过重定向方式返回给 Client 呢?如果直接返回 access_token,协议将变得更加简洁,而且少一次 Client 与 AS 之间的交互,性能也更优。那为何不这么设计呢?协议文档中并没有给出这样设计的理由,但也不难分析:

  1. 浏览器的 redirect_uri 是一个不安全信道,此方式不适合于传递敏感数据 (如 access_token)。因为 uri 可能通过 HTTP referrer 被传递给其它恶意站点,也可能存在于浏览器 cacher 或 log 文件中,这就给攻击者盗取 access_token 带来了很多机会。另外,此协议也不应该假设 RO 用户代理的行为是可信赖的,因为 RO 的浏览器可能早已被攻击者植入了跨站脚本用来监听 access_token。因此,access_token 通过 RO 的用户代理传递给 Client,会显著扩大 access_token 被泄露的风险。但 authorization_code 可以通过 redirect_uri 方式来传递,是因为 authorization_code 并不像 access_token 一样敏感。即使 authorization_code 被泄露,攻击者也无法直接拿到 access_token,因为拿 authorization_code 去交换 access_token 是需要验证 Client 的真实身份。也就是说,除了 Client 之外,其他人拿 authorization_code 是没有用的。此外,access_token 应该只颁发给 Client 使用,其他任何主体 (包括 RO) 都不应该获取 access_token。协议的设计应能保证 Client 是唯一有能力获取 access_token 的主体。引入 authorization_code 之后,便可以保证 Client 是 access_token 的唯一持有人。当然,Client 也是唯一的有义务需要保护 access_token 不被泄露。
  2. 引入 authorization_code 还会带来如下的好处。由于协议需要验证 Client 的身份,如果不引入 authorization_code,这个 Client 的身份认证只能通过第 1 步的 redirect_uri 来传递。同样由于 redirect_uri 是一个不安全信道,这就额外要求 Client 必须使用数字签名技术来进行身份认证,而不能用简单的密码或口令认证方式。引入 authorization_code 之后,AS 可以直接对 Client 进行身份认证 (见步骤 4 和 5),而且可以支持任意的 Client 认证方式 (比如,简单地直接将 Client 端密钥发送给 AS)。

消息认证码算法及原理

基于 Web 安全的考虑

OAuth 协议设计不同于简单的网络安全协议的设计,因为 OAuth 需要考虑各种 Web 攻击,比如 CSRF (Cross-Site Request Forgery)、XSS (Cross Site Script)、Clickjacking。要理解这些攻击原理,读者需要对浏览器安全 (eg, Same Origin Policy, 同源策略) 有基本理解。

比如,在 redirect_uri 中引入 state 参数就是从浏览器安全角度考虑的,有了它就可以抵制 CSRF 攻击。如果没有这个参数,攻击者便可以在 redirect_uri 中注入攻击者提供的 authorization_code 或 access_token,结果可能导致 Client 访问错误的资源 (比如,将款项汇到一个错误的帐号)。


以上参考:

帮你深入理解OAuth2.0协议

OAuth 认证流程详解

OAuth 2.0的机制原理讲解及开发流程

OAuth (Open Authorization, 开放授权), OpenID

OAuth2.0 鉴权 (微信公众平台、腾讯微博)

理解OAuth 2.0

Oauth2.0与Oauth1.0的区别

OAuth、OAuth与OpenID区别和联系

OAuth

帮你深入理解OAuth2.0协议

MAC_Message Authentication Code_消息认证码算法

图解Browser端访问OAuth2 API的安全性问题与解决方案

版权所有,转载请注明出处 luowei.github.io.