试想像有一座房子,里头有无数房间。而你作为这座房子的管家,拥有一把万能钥匙,可以打开房子内所有的门。 此外,这把万能钥匙还有一个作用,就是产生出开启特定门的钥匙。 你可以将新产生出的钥匙交给其他人,其他人就可以自由进出特定房间。这个动作就是「授权」。
OAuth 是一个开放标准的授权协议 ,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥有者的资源。应用向资源拥有者请求授权,然后取得令牌(token),并用它来访问资源。这一切都不需要应用去充当资源拥有者的身份,因为令牌明确表示了被授予的访问权。
众所周知,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.2
OAuth 2.0 框架能让第三方应用以有限的权限访问 HTTP 服务,可以透过构建资源拥有者与 HTTP 服务间的许可交互机制,让第三方应用代表资源拥有者访问服务,或者通过授予权限给第三方应用,让其代表自己访问服务。
作为一个 授权框架 ,OAuth关注的是如何让一个系统组件获取对另一个系统组件的访问权限。我们需要关心如下组件:
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 就是执行身份验证。这种想法不仅是错误的,而且会给服务提供商、开发人员和最终用户带来危险。
开发人员试图发明一个协议,允许用户将 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 可能也不是一个完美的协议,但从现实层面来看,今天的它非常流行,以至于开发者几乎不能不知道。
对于一个应用来说,最重要的是它的业务逻辑 。 除了业务逻辑本身,为完成所需的工作,会需要取得必要之资源。这可能是一份档案, 镜头、麦克风资源等不同种形式。
在 取得资源 过程中,也会有另外一层业务逻辑,也可能本身就是另一只程序服务,对所需取得的资源,进行 访问控制 。
最后,为了判断是否具有存取该项资源的权限,有可能有必要进行 身份验证或授权 。
在上面例子,「身份验证/授权服务」可能是身份服务器和授权服务器;「访问控制服务」可能是资源服务器。 但也有不少做法是将身份和授权做在一起,资源访问控制直接由应用(业务逻辑)处理。更甚者,身份验证于应用的不同逻辑层的状况也不少见。
{plantuml} @startuml actor 使用者 as user participant 业务逻辑 as business participant "身份验证/授权\n服务" as id participant "访问控制\n服务" as ac user -> business: 1. 使用应用服务 business -> ac: 2. 要求取得某项资源 ac -> ac: 3. 检验访问权限 ac -> id: 4. 要求确认身份/授权 id -> user: 5. 要求证明身份\n 或要求授权 user --> id: 6. 证明身份或授权 id -> id: 7. 检验身份或授权 id --> ac: 8. 返回身份或授权 ac -> ac: 9. 检验访问权限 ac --> business: 10. 返回资源 business -> business: 11. 处理业务逻辑 business -> user: 12. 完成业务逻辑 @enduml {plantuml} |