Oauth2.0(二)

Oauth2.0(二):开放平台

  上一节说到Oauth2.0 的交互模型。模型涉及到三方:资源拥有者、客户端、服务提供方。其中,服务提供方包含两个角色:鉴权服务器和资源服务器。鉴权服务器负责对用户进行认证,并授权给客户端权限。认证这一步好实现,无非就是验一下账号密码。但是授权这一步怎么做?可以看到在QQ的授权页面上,有”有道云笔记将获得以下权限“的字样以及权限信息。鉴权服务器需要知道请求授权的客户端的身份以及该客户端请求的权限。所以,需要在谈完合作之后,为每一个客户端预先分配一个 id,并给每个 id 对应一个名称以及权限信息。这些信息可以写在鉴权服务器上的配置文件里。然后,客户端每次打开鉴权页面的时候,把属于自己的 id 传过来,像这样:

  http://xxx.xxx.com/oauthPage?client_id=xxx

  鉴权服务器就可以根据这个 id 去展示授权信息了。

  这个流程是 ok 的。但是,随着时间的推移和业务的增长,会发现,修改配置的工作消耗了太多的人力。有没有办法把这个过程自动化起来,把人工从这些繁琐的操作中解放出来?当开始考虑这一步,开放平台的成型也就是水到渠成的事情了。

  开放平台是由 Oauth2.0 协议衍生出来的一个产品。它的作用是让客户端自己去这上面进行注册、申请,通过之后系统自动分配 client_id ,并完成配置的自动更新(通常不是配置文件,而是写进数据库)。

  开放平台的一个实例:http://open.weibo.com/

  客户端要完成申请,通常需要填写客户端程序的类型(web、移动端app等)、企业介绍、执照、想要获取的权限等等信息。这些信息在得到服务提供方的人工审核通过后,开发平台就会自动分配一个 client_id 给客户端了。

  到这里,已经实现了登录认证、鉴权页的信息展示。那么接下来,当用户成功进行授权之后,鉴权服务器需要把产生的 access token 发送给客户端。这一步,怎么做?

  方案是这样的:让客户端在开放平台申请的时候,填写一个 url,例如:

  http://www.abc.com

  然后。每次当有用户授权成功之后,鉴权服务器将页面重定向到这个 url ,并带上 access token。这一步叫做回调。例如:

  http://www.abc.com?accesstoken=xxxxxxxx

  这样,客户端就接收到了这个 access token,而且鉴权服务器的授权动作已经完成,刚好可以把程序的控制权转交回客户端,由客户端决定接下来向用户展示什么内容。


Oauth2.0(三):Access Token 与 Refresh Token

  access token 是客户端访问资源服务器的令牌。拥有这个令牌代表着得到用户的授权。然而,这个授权应该是临时的,有一定有效期。这是因为,access token 在使用的过程中可能会泄露。给 access token 限定一个较短的有效期可以降低因 access token 泄露而带来的风险。

  然而引入了有效期之后,客户端使用起来就不那么方便了。每当 access token 过期,客户端就必须重新向用户索要授权。这样用户可能每隔几天,甚至每天都需要进行授权操作。这是一件非常影响用户体验的事情。希望有一种方法,可以避免这种情况。

  于是 Oauth2.0 引入了 refresh token 机制。refresh token 的作用是用来刷新 access token。鉴权服务器提供一个刷新接口,例如:

  http://xxx.xxx.com/refresh?refreshtoken=&client_id=

  传入 refresh token 和 client_id,鉴权服务器验证通过后,返回一个新的 access token。为了安全,Oauth2.0 引入了两个措施:

  1,Oauth2.0 要求,refresh token 一定是保存在客户端的服务器上的,而绝不能存放在狭义的客户端(例如移动 app、PC端软件) 上。调用 refresh 接口的时候,一定是从服务器到服务器的访问;

  2,Oauth2.0 引入了 client_secret 机制。即每一个 client_id 都对应一个 client_secret。这个 client_secret 会在客户端申请 client_id 时,随 client_id 一起分配给客户端。客户端必须把 client_secret 妥善保管在服务器上,决不能泄露。刷新 access token 时,需要验证这个 client_secret。

  于是,实际上的刷新接口应该是类似这样的:

  http://xxx.xxx.com/refresh?refreshtoken=&client_id=&client_secret=

  以上就是 refresh token 机制。refresh token 的有效期非常长,会在用户授权时,随 access token 一起重定向到回调 url,传递给客户端。

Oauth2.0(四):Implicit 授权方式

  Oauth2.0的核心机制已经总结完毕。除了核心机制,Oauth2.0 还提供了几种标准的授权流程,分别适用于不同的场景。其中一种叫做 Implicit 授权,适用于纯静态页面应用。所谓纯静态页面应用,也就是应用没有在服务器上执行代码的权限(通常是把代码托管在别人的服务器上),只有前端 Js 代码的控制权。

  这种场景下,应用是没有持久化存储的能力的。因此,按照 Oauth2.0 的规定,这种应用是拿不到 refresh token 的。其整个授权流程是这样:

  对于这种应用,access token 是容易泄露的,且不可刷新。

Oauth2.0(五):Authorization Code 授权

  Authorization Code 方式适用于有自己的服务器的应用。之所以叫这个名字,是因为流程中引入了一个叫做 authorization code 的东西。这个东西是一个一次性的临时凭证,用来换取 access token 和 refresh token。

  鉴权服务器提供了一个类似这样的接口:

  https://www.xxx.com/exchange?code=&client_id=&client_secret=

  需要传入 code、client_id 以及 client_secret。验证通过后,返回 access token 和 refresh token。一旦换取成功,code 立即作废,不能再使用第二次。

  为什么要引入一个一次性的 code?

  先看流程图:

  这个 code 的作用是保护 token 的安全性。上一节说到,Implicit 方式下,token 是不安全的。这是因为在 4 这一步当中直接把 token 返回给应用。而这一步容易被拦截、窃听。引入了 code 之后,即使攻击者能够窃取到 code,但是由于他无法获得应用保存在服务器的 client_secret,因此也无法通过 code 换取 token。而 5 这一步,为什么不容易被拦截、窃听呢?这是因为,首先,这是一个从服务器到服务器的访问,黑客比较难捕捉到;其次,这个请求通常要求是 https 的实现。即使能窃听到数据包也无法解析出内容。

  有了这个 code,token 的安全性大大提高。因此,Oauth2.0 鼓励使用这种方式进行授权,而 Implicit 方式则是在不得已情况下才会使用。

Oauth2.0(六):Resource Owner Password Credentials 授权和 Client Credentials 授权

  这两种简称 Password 方式和 Client 方式吧,都只适用于应用是受信任的场景。一个典型的例子是同一个企业内部的不同产品要使用本企业的 Oauth2.0 体系。在有些情况下,产品希望能够定制化授权页面。由于是同个企业,不需要向用户展示“xxx将获取以下权限”等字样并询问用户的授权意向,而只需进行用户的身份认证即可。这个时候,由具体的产品团队开发定制化的授权界面,接收用户输入账号密码,并直接传递给鉴权服务器进行授权即可。

  有一点需要特别注意的是,在 2 这一步,鉴权服务器需要对客户端的身份进行验证,确保是受信任的客户端。

  如果信任关系再进一步,或者调用者是一个后端的模块,没有用户界面的时候,可以使用 Client 方式。鉴权服务器直接对客户端进行身份验证,验证通过后,返回 token。

  这两种方式在 Oauth2.0 协议中是不推荐使用的。只要条件允许,就应该使用 Authorization Code 方式。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值