注:阅读之前忘掉授权码、token那一套,只理解这个模型

参考来源

模型

OAuth2.0提供了一种客户端获取资源的授权模型,这一模型解决了客户端在获取他人资源时不必要求资源持有者提供明确的身份验证信息,而把这个任务交给了一个可信任的授权者,这个授权人对资源的持有人是可信任的,对资源的托管方也是可信任的。
因此,OAuth2.0规范定义了四种角色:

  • 首先,客户端的意图很明确,向资源服务器获取资源;
  • 这个时候客户端需要出示一个凭证——令牌;
  • 令牌由授权服务器颁发,资源服务器在拿到令牌之后自己想办法验证令牌的合法性;
  • 因此,客户端的上一步就需要想办法去授权服务器拿到 目标资源 的令牌
  • 授权服务器保存了资源所有者的身份信息,因此,客户端需要取得资源所有者的同意,从而向授权服务器拿到授权的凭证,这一步由客户端引导资源所有者授权服务器进行身份校验,促使授权服务器客户端一个授权凭证(这个授权的凭证意味着资源所有者认可客户端的合法性,说明客户端有获取令牌的资格);
  • 客户端在取得这个资格之后,可以放心地向授权服务器请求资源凭证——令牌;
  • 在拿到令牌之后,客户端可以放心地去资源服务器请求资源所有者指定的资源

这么做有个前提:资源持有者认可当前客户端。这个就要靠持有人自己负责验证客户端的合法性了。
这么做的好处就是:令牌的解释权在授权服务或资源服务器,资源持有人可以随时通知两者,使令牌失效。

四种模式

授权码模式(Authorization Code)

授权服务器发放这个资格的一个方式,就是提供一个短时间有效的授权码,客户端想拿到这个授权码,就要遵循授权服务器提供的授权码发放方式:

  1. 一般是客户端提供场地(代理,一般是浏览器),把授权服务器的认证机制拿到
  2. 资源持有者按照认证机制和授权服务器交互完成
  3. 然后归还场地,留下认证成功的资格--授权码
    这是一种牵线搭桥的方式,典型的就是微信的授权登录,在手机扫码完成之后,把验证成功的一个 code 通过回调地址给传回来。

简化模式(implicit)

认证,也就是获取授权码的那一步,其实是可以直接返回令牌的,于是:

  1. 客户端被分配一个身份id(appKey 或 client_id),表明这就是一个可以相信的客户端
  2. 客户端直接带着身份 id 和一个用于回传的地址跳转到授权服务器,触发和资源持有者的交互
  3. 在交互成功后,授权服务提供一段 html 或 JavaScript 脚本,把认证成功的信息(主要是令牌)顺着回传地址带回给客户端

由于两次跳转都是发生在代理上,因此向授权服务器跳转的地址,和回传地址都可以伪造,指向一个自定义的服务(中间人),因此这种方式适合令牌有效时间不能太长。

密码模式(resource owner password credentials)

当客户端足够可信时,授权服务甚至可以提供一种更加直接的方式,让客户端直接把认证信息发过来,最普遍的就是资源持有者直接在客户端输入用户名、密码。
授权服务在认证成功后,直接返回令牌。
较简化模式,连回传都省了,不过这个应用范围很小,基本都是应用内部或系统内部使用的。

客户端模式(client credentials)

当然了,我们可以继续简化,用户名、密码都不要了,客户端发过来一个身份id,直接颁发令牌。只要一个链接,带上身份 id 就可以。
由于不需要资源持有者参与,因此令牌是和客户端绑定的,向资源服务请求的也是客户端自己的资源。

总结

OAuth2.0 提供了一种基于认证+授权的机制,由客户端发起,通过一个代理(一般是浏览器),资源持有者授权服务进行认证交互,最终向发起者——客户端颁发一个有时效的令牌的过程。

03-05 15:24