Day10 - 【概念篇】深入OAuth 2.0

本系列文之後也会置於个人网站


喔不,其实今天还不会真正提到OAuth 2.0的深度内容。今天要来谈谈的是取得资源的细节。

使用帐号密码,假装自己是用户

首先先试着想想看,如果你想要写一支程序代替你处理某些事情。譬如:收信、发信。
更详细的说,你写了一个信件的客户端(如:Thunderbird、Outlook)。
然後你会需要告诉这支程序你信箱的登入帐号密码,由他去代替你收信、寄信。这个样子就像是你把你所有的秘密都交给了它,交给了它那把万能钥匙,而你完全信任这支程序。

其实这种状况还真不少见。尤其在於你所申请的帐号,和使用的客户端服务实际就是同一个时,这种行爲在正常不过。

但当它们是不同服务时,就可能出现问题了。你还能信任你提交的密码不会被误用吗?不可能发生?

你可能有Gmail的帐号,你会很正常的使用Gmail的服务。但你知道Gmail除了自己本身外,它还可以帮你收其他信箱吗?

比如说你还有ymail的帐号,但你更喜欢Gmail的界面,所以你希望使用Gmail来处理yamil的信件。这时候其实你就是告诉了Gmail关於yamil的帐号密码。相对的,也就是你应该是信任的Google的服务。

当在使用的服务是同一个提供商时,这种直接使用帐号密码的情况就相当正常。他们本就可以共用一些资讯,可能使用了相同的记忆体空间、使用了相同的资料库等。

但或许你该留意使用的真的是同一个服务,还是其实是一个代理(Proxy)?

当使用代理时,这样的情况,这个代理有可能短暂的持有你的帐号密码资讯。

特殊密码

我们将这个代理,再扩展一些。它或许不只是一般的软件,更是作业系统,乃至硬体。

想想,你一般使用私人电脑收信。但偶尔,你会需要使用公司电脑、公共电脑登入。尽管或许你还是使用Gmail的服务,但实际上这之中通过了好几层代理。

首先,硬体、作业系统上你不知道有没有安装硬体键盘记录器。接着浏览器也同样是一个代理,使用的是可信任的浏览器吗?

那该怎麽办?我们可以与服务约定一种「特殊密码」。这种密码只能使用一次,是一次性密码(OTP, One Time Password)。
现在一次性密码更常见到於二阶段验证(双因子验证/2FA, Two Factor Authentication)。但实际上存在非常多种形式:

  1. 透过简讯验证: 透过简讯寄送一组限时且只能使用一次的密码
  2. 透过信箱验证: 透过信箱寄送一组限时且只能使用一次的密码
  3. 特殊连接验证: 透过一个特殊的连接,该连接有时效性,且只能存取一次。
  4. 透过时间产生特殊密码: TOTP, Time-base One Time Password。
  5. 透过杂凑产生特殊密码: HOTP, HMAC-based One Time Password。
  6. 与系统服务约定好数组一次性密码
  7. 与系统服务约定好特殊状况使用密码
  8. 使用行动装置登入

当然可能远不止这些,其中简讯、信箱寄送验证密码或许有相当多人用过。所以也就挑几个来说说:

第3个,如果你有使用过Medium、Notion 、Tumblr 的话,他们都可以透过信箱寄送一个 神奇的连接 让你登入。

第6个,实际你在使用Android的话,Google有储存几组动态的在你的手机,虽然这可能更像是第4、5个。(iPhone好像也有,有段时间Facebook也可产生)

第7个,同样可以申请一组在特定情况使用的密码。像是Facebook可以申请应用程序密码。当在使用非Facebook的应用程序,但需要使用Facebook登入时,
不必输入Facebook的密码,只要输入这个特殊密码即可。

开发者权杖

还有一种情况是,你本身在开发的应用本就是系统服务框架下的一部分,你本身就是开系统的开发人员之一。你已可能有一把非常强大的开发者钥匙(密码或权杖)。
你或许会去验证使用者身份或许不会,但你直接使用这个钥匙来处理服务。

爲什麽会有这种情况?或许该子服务本身就设计成只有开发者权杖,细部控制并不够精细,所以需要一个看门人(gatekeeper)来检查是否有权限操作服务。

委托授权

以上,虽然有一点授权的味道了,但是都是 整份授权 。都还没有把权限拆分更小的部分分开授权,相对的更接近验证的部分。

委托概念是 OAuth 强大功能的根基。虽然 OAuth 经常被称作授权协议(这是RFC中给出的名称),但它也是一个委托协议。 通常,被委托的是用户全向的子集,但是 OAuth 本身并不承认或传递权限。相反,它提供了一种方法,让客户端可以请求用户将部分权限委托给自己。然後,让用户可以批准这个请求。批准之後,客户端就可以去执行这些操作了。
-- OAuth 2.0实战

还记得在「什麽是OAuth」说过: OAuth没有定义权杖格式 。 所以它可以很像是上面提到的特殊密码,不同的是现在不将整份权限授权出去,而只授权一部分。

在我们「快速开始」有这麽一个操作画面:

我们只授权了该应用存取角色、Email资讯和帐号资讯,并且最後会产生一组特殊密码。

但由於OAuth委托过程需要资源拥有者参予。需要拥有者确认授权这件事情或许不是每种情况都可以做,所以你可以将其设计爲白名单、灰名单和黑名单。

  • 白名单: 不需要用户的明确授权。 适用於内部可信任的机构或团体。
  • 灰名单: 采用用户首次使用时确认。 由用户决定是否加入白名单或黑名单。
  • 黑名单: 由集中控制机构,决定是否放行应用。

此外你会注意到,在之後登入「快速开始」应用时,并没有在要求授权一次。 这是基於 首次使用时信任原则(TOFU, Trust On First Use)

你可以透过 http://localhost:8080/auth/realms/quick-start/account/#/applications 来查看已经授权的应用,同样也可以用来撤销授权。

参考资料


<<:  【Day 11】Button Template 应用 part 2

>>:  Day 11 打包 python 程序-3

D20. 学习基础C、C++语言

D20. 字串题练习 这题是之前老师出的题目但是我一直解不出来,後来看很久,还跑去问同学才解出来的,...

从零开始的8-bit迷宫探险【Level 17】稻草人也想要智慧大脑,给怪物一点灵魂跟一点点个性

「我们不能漫无目的地追,要拟定包夹计画!」Rain 大声地说,并展露出大哥是对的姿态。 「我去魔幻...

【Side Project】 点菜单功能实作 - 建立关联式的资料表

上一篇我们说到怎样才算是把菜单送到老板手上呢? 送出菜单有两个步骤 顾客送出菜单 老板接收菜单 我们...

Day30 file system, inode

前言 时间终於过到了最後一天,昨天看了三个特别的虚拟文件系统,今天就看看实际存在的文件管理系统吧! ...

Day17-TypeScript(TS)的继承(Inheritance)

今天要来介绍TypeScript(TS)的继承(Inheritance), 这项在TS之中也是相当重...