Day07 - 【入门篇】什麽是OAuth

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


先来回忆一下,何爲「授权」。试想像有一座宅邸,里头有无数房间。而你作爲这座宅邸的管家,拥有一把万能钥匙,可以开始宅邸内所有门扉。
此外,这把万能钥匙还有一个作用,就是产生出开啓特定门扉的钥匙。
你可以产生出的钥匙交给其他人,其他人就可以自由进出特定房间。这个动作就是「授权」。

OAuth 是一个开放标准的 授权协议 ,它允许 软件应用 代表 资源拥有者 访问资源拥有者的 资源 [^OAuth-2.0实战]。

[^OAuth-2.0实战]: OAuth 2.0实战

OAuth是什麽?

OAuth 2.0 是一个授权协议,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥
有者的资源。应用向资源拥有者请求授权,然後取得令牌(token),并用它来访问资源。这一切
都不需要应用去充当资源拥有者的身份,因为令牌明确表示了被授予的访问权。
-- OAuth 2.0 实战

众所周知,OAuth是一个安全协议,协议规范是这样定义的:

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.[^RFC_6749]
OAuth 2.0 框架能让第三方应用以有限的权限访问HTTP服务,可以透过构建资源拥有者与HTTP服务间的许可交互机制,让第三方应用代表资源拥有者访问服务,或者通过授予权限给第三方应用,让其代表自己访问服务。[^OAuth-2.0实战]

[^RFC_6749]: RFC 6749

作爲一个 授权框架 ,OAuth关注的是如何让一个系统组件获取对另一个系统组件的访问权限。我们需要关心如下组件:

  • 资源拥有者 能将访问授权委托出去。
    资源拥有者指的是使用者本身,或在系统中的帐号。起初的OAuth设计是基於HTTP的,所以可以理解爲坐在浏览器前的人。
    或是本节一开始举的例子--宅邸的管家--。将访问授权委托出去的过程,就是利用万能钥匙产生出其他有限钥匙并转交他人的过程。
  • 某种受保护资源 。 OAuth并不关心受保护资源长什麽样子,可能是个RESTfule API、某个页面、URI所识别的其他种类资源。
    就像是宅邸里每一个房间。
  • 客户端 。 还记得在「快速开始」建立的「my-quick-start-app」吗?客户端指的就是代表资源拥有者访问受保护资源的软件。
    也就是将产生出的钥匙转交给「他人」。

OAuth 不是什麽?

  • OAuth 不是身份验证协议
    虽然可以基於OAuth进行身份验证,就如同在「快速开始」的例子。但其关注的重点仍在授权而非身份验证。
  • OAuth 没有定义用户对用户的授权机制
    同样不是不行,但它根本上是一个用户向应用软件授权的协议。它甚至不关注存取控制。
  • OAuth 没有定义授权处理机制
    虽然OAuth定义了一些授权框架/流程,但不定义授权的内容。相反,由服务API定义使用授权范围,允许权杖适合哪些操作。
  • OAuth 没有定义权杖格式
    OAuth协议明确申明了权杖的内容对於客户端是完全不透明的。虽然权杖本身对於客户端是不透明的,但接受权杖处理的服务,仍然需要理解权杖。
    换句话说授权服务器产生权杖,但对於权杖的理解全依赖於资源服务器。
    同本节一开始的例子,万能钥匙产生了新的房门钥匙。但这把钥匙实际能不能够使用,由门锁直接决定。与拿到钥匙的人、管家没有直接关系。
  • OAuth 2.0 没有定义加密方法
    尽管爲了安全,诸多服务如Google、Spofity都会要求客户端支援HTTPS。但框架本身同样不关注这部分,也不管权杖如何签名、加密、验证。
  • OAuth 2.0 不是单体协议
    从上述来看,该规范被分成多个定义和流程,每个定义和流程都有各自适用的场景。

OAuth 2.0 规范定义了一个授权协议,用户在Web应用以及API之间传递授权决策。因爲OAuth 2.0用於获取已经通过身份验证的最终用户的许可,所以很多开发人员和API服务商认爲OAuth 2.0是一种让用户安全登入的身份认证协议。然後,尽管OAuth 2.0是宜个需要用户交互的安全协议,但并不是身份认证协议。我门要明确地重申一遍:

OAuth 2.0 不是身份认证协议。

之所以会产生如此多的误解,是因爲OAuth 2.0经常被用於身份认证协议内部,而常规的OAuth 2.0流程内部也会包含一些身份验证事件。所以,很多开发人员看到这样的OAuth 2.0流程,以爲使用OAuth就是执行身份验证。这种想法不仅是错误的,而且会给服务提供商、开发人员和最终用户带来危险。
-- OAuth 2.0 实战

OAuth 1.0

开发人员试图发明一个协议,允许用户将API访问授权出去。新的协议基於多个具有同样思想的专有实现,包括Google的AuthSub以及Yahoo!的BBAuth。在这些实现中,客户端应用只要获得用户的授权并得到一个权杖,就能够使用这个权杖访问远端API。这些权杖的发放都包含公共和私有的部份,并且该协议使用了一种新型的(现在看来是脆弱的)加密签名机制,使得它可以在非TLS HTTP连接上使用。他们称为这个协议为OAuth 1.0,并将其作为一项Web开放标准发布,它很快获得响应,出现了多种语言对这一标准的自由实现。这一标准表现优秀,深得开发人员喜爱,甚至一些大型网路公司也很快弃用了自己的专有机制,起初正是这些专有机制启发了OAuth。
-- Justin Richer

OAuth 2.0 并不相容於 OAuth 1.0 。但相关概念最早始於2006年11月。现在看到的OAuth应该大多都直接是指 OAuth 2.0 。在2009年4月30日。 OAuth 1.0 被发现一个安全漏洞。同样地, OAuth 2.0 可能也不是一个完美的协议,但从现实层面来看,今天的它非常流行,以至於开发者几乎不能不知道。

OAuth碳 (OAuth-tan)

除了由Chris Messina绘制并提交给社区OAuth的公共汽车乘车币标志。OAuth协议甚至还有一个超级酷的非官方吉祥物: OAuth碳 (OAuth-tan)


结语

OAuth 无意用一个大而全的协议去解决安全系统所有方面的问题,而是只专注於一件事情,
把剩下的问题留给其他组件,让它们各专所长。
-- OAuth 2.0 实战

就是因爲这样专注一件事,刻意馍糊部分,所以OAuth有非常高的弹性,适用於多种不同情境。但也相对的并不那麽容易理解,且实践过程中还有可能踩入反模式,反而照成威胁。

OAuth是一个非常强大的工具,它的强大来自其灵活性,灵活性通常意味着它不仅能够完成你的构想,而且也会带来安全问题。OAuth管理API的访问权限,守护着重要资料,所以最关键的是避免反模式,运用最佳实践,以安全的方式使用它。换句话说,虽然它的灵活性能让你可以以任何方式使用和部署它,但并不意味着你应该那样随意。

关於OAuth,还有一件要提到的事情——你不是为了用OAuth而去用它。你是想用它来做一些别的事情——很可能是要将一组API调用精心组合起来,以实现一个绝妙的点子。你或许正在头脑中勾勒遗符完整的图景,正思考如何实现自己的杰作。OAuth可以帮助你以更安全的方式实现它。
—-Ina Glazer, Saleforce公司身份管理高级总监

我们也差不多到入门篇的尾声了,但我会强力建议你继续阅读之後的内容。毕竟:

与所有工具一样,了解工具的工作原理及其优点非常重要。毕竟,用锤子虽然可以将螺丝钉打入墙壁,但用螺丝刀可能会更省力。希望你了解OAuth适用於哪些场景,同样也了解它不适用於哪些场景。

参考资料


<<:  [Java Day12] 3.6. break & continue

>>:  【Day8】ERP核心模组篇-Invoicing

DAY 6 『 TableView 』Part1

TableView:Storyboard + Table View + Table View Cel...

Day02 WebRTC 简介

一场全球大流行的 COVID-19 疫情,以及 H264、H265、VP8、VP9等影音压缩技术加...

OpenStack 介绍 1

本系列文章同步发布於笔者网站 我们在前几一篇文章叙述本次铁人赛所会架出的云端架构了,今天开始的文章将...

[Day09] JavaScript - 流程判断

if...else 当条件成立的时候执行 if 内的陈述式,不成立时则执行else的陈述式。 语法 ...

Day29 切版笔记 -订单进度条

今天来练习切这个画面 运用到的观念 flexbox google fonts 字体& ico...