【进阶技术】一篇文章搞掂:OAuth2

时间:2022-06-13 17:15:38

一、第一步

1、什么是OAuth2,为什么应该了解

 

应用程序请求资源所有者进行认证,并接受tokens来访问这些资源
应用程序不是以控制资源的“人”的角度去访问资源,而是用许可证
举例,备用钥匙,车主主钥匙就像“人”,拥有他的所有权限;但是备用钥匙,虽然不是“人”,但是也代表了一些有限功能,仍然能实现把开关车门的权限。

重点是token


例子:有2个服务,图片打印,图片存储,运行在2个不同的电脑,是2个不同的程序,他们之间通过API来管理
而2边的帐号管理是分开的
我们可以使用OAuth2,来解决这个问题,而不用把你的密码从打印程序中发出到存储程序中去

resource owner:
资源所有者可以访问API,并可以委托对该API的访问。
资源所有者通常是一个人,且一般假定有权访问一个web浏览器。
因此,这本书的图表用一个人坐在浏览器前来表示

protected resource:
受保护的资源是资源所有者可以访问的组件。
资源有很多不同的形式,最多见的是一个webAPI。
资源这个词听起来是下载的API,但实际上是可以读写或其他操作。
这本书的图表用一个带锁的服务器来表示受保护资源

client:
指代表资源所有者去访问受保护资源的一系列软件。
在OAuth中,客户端是指消费受保护资源中的API的任何软件。
这本书的图表用一个带齿轮的电脑屏幕代表客户端。
这是因为客户端有太多形式,没有办法去找到一个合适的图标。

明确目标:让客户端代表资源所有者,去访问受保护的资源

【进阶技术】一篇文章搞掂:OAuth2

 

例子:我希望打印一张图片,那么打印软件需要调用存储软件的API,此时,打印软件就是对应该API的Client,我作为resource owner,可以时委托打印软件这个Client,授予它一部分权力,去访问存储软件,同时,这个权力也仅限于获取需要打印的图片,而不能获取其它图片或者删除图片

这里有一张图片可以插入 P33

1.2、以前的做法:凭证分享与凭证盗窃
需要连接多个分开的服务这种需求,很早已经有
一种做法:复制用户凭证并传递给另外一个服务
这里没有细看,主要说2个系统可以共享验证系统,然后调用时传递帐号密码过去,伪装成用户
这样,如果其中一个系统暴露了密码,相当于所有系统都暴露了。
而且保护的资源无法确定某个请求是来自真人,还是来自客户端的一次调用,结果客户端的调用会拥有真人的所有权限。
客户端也可以盗取你的密码,然后偷偷地访问你保护的资源

【进阶技术】一篇文章搞掂:OAuth2

【进阶技术】一篇文章搞掂:OAuth2

 

Lightweight Directory Access Protocol (LDAP) authentication

另外一种做法:developer key
客户端可以伪装成任何用户,例如通过API参数,这样可以不暴露客户端
但是客户端需要一个十分强大凭证,拥有所有权力
这个只适用于客户端对于保护程序来说是完全绝对信任的情况

【进阶技术】一篇文章搞掂:OAuth2

 

还有一种做法,给予用户一个特别的密码,专门来访问第三方服务
增加了维护成本,

【进阶技术】一篇文章搞掂:OAuth2

 

 

!!委托访问

OAuth是一个协议,在访问受保护资源的时候,是这样做的:

资源所有者,把一部分权限,委托给Client,Client再去访问Protected Resource。

要实现这个做法,OAuth加入了另外一个组件Authorization Server

保护的资源,信任验证服务器,验证服务器会发出特殊目的的安全凭证:OAuth access token,访问令牌,给客户端。

获取令牌:

  客户端先把资源所有者发送给验证客户端,目的是让资源所有者授权此客户端

  验证服务器对资源所有者进行身份验证,然后决定是否授权给请求的客户端

  客户端可以获取权限的子集,或者一个范围内的权限。

  授权完成,客户端可以从验证服务器请求到一个令牌。

  然后,客户端就可以用这个令牌去访问API,因为资源所有者已再验证服务器授予了对应权限。

【进阶技术】一篇文章搞掂:OAuth2

【进阶技术】一篇文章搞掂:OAuth2

这样,任何时候客户端都不会得到用户的帐号密码。

  1、客户端要访问OAuth保护的资源,则需要授权,告诉资源所有者,需要授权

  2、资源所有者,到验证服务器上,注册该客户端,并指明了其响应权限

  3、客户端现在可以请求验证服务区授权了

  4、认证通过后,验证服务器返回一个token

  5、客户端使用这个token,访问受保护资源

  6、受保护资源识别(如何识别?)到令牌所表达的权限,如果有对应API的权限,则正确运行

 

 超越HTTP Basic和密码共享反模式

再OAuth前面介绍的例子,都是密码反模式,直接使用密码来代表提问方。这种方式会导致密码泄露。

 

如何让HTTP APIS把密码保护放在第一位呢,HTTP协议的安全方法也有相关启示。

HTTP协议使用HTTP Basic Auth协议,来让用户通过账号和密码来认证一个web页面

更有一个安全点的版本叫HTTP Basic Auth

但是他们共同的一点是,他们都需要用户在场,且需要想HTTP服务器提供帐号密码

而且,http协议是无状态协议,所以这些帐号密码,在每一次http操作都要重新提交

 

HTTP期初是作为文档访问协议,所以这些都是有意义的。但是随着时代发展,web的使用范围有了显著的增长。

HTTP协议在用户使用浏览器进行操作时,或其它软件直接通过HTTP来进行某些操作时,是没有区别的。这种灵活性使得HTTP协议的成功和被人们接受

但结果,当HTTP 开始用于直接访问api,除了面向用户的服务,它的存在这个新的用例很快采用了安全机制

这一简单的技术也导致长期滥用用户的密码。

在浏览器,有cookies和其它session处理技术,但是在其他HTTP客户端直接访问API时则没有这些技术。

 

OAuth一开始就是设计为使用API的协议,主要交互和浏览器无关。

通常是有一个用户在浏览器中启动这个进程,这就是这个委托模型的灵活性和强大所在之处,然后获取token以及使用token来访问保护资源,都在用户的可见范围外。

实际上,很多关联用例并不在用户看到的界面发生,但是OAuth客户端仍然能作为用户的代表,来进行一些HTTP请求和操作。

OAuth允许我们超越HTTP基本协议,而使用一种更加强大、安全的工作方式,以应对今天的基于API经济。

 

1.3.2、授权委派:为什么很重要以及如何使用他

委派这个概念,是OAuth能力的基础。

虽然OAuth经常被称为认证协议,但是他是一个委派协议。

通常,用户权限的一个子集会委派出来,但OAuth本身并不携带和传递这些授权。

而是让客户端,自己请求其所拥有的权限。

然后用户审核这些请求,然后客户端就可以使用这些请求结果来进行下一步操作。

 

例如打印软件,打印某张图片时,会询问用户:“你是否有需要打印的图片在存储软件中的读取权限?如果有,那么我们打印”。

然后用户被发送到存储软件服务,存储软件问用户:打印软件需要打印你的某张图片,是否允许其操作?此时用户可以觉得是否授予打印软件这个Client这个权限。

委派协议和授权协议的区别很重要,因为OAuth token所携带的权限对大部分系统都是不透明的。

只有受保护的资源才知道其中权限,只要从token以及其所代表的上下文中就可以找到,可能是通过API的方式。

 

1.3.3、用户驱动的安全性以及用户的选择

传统方式,通常有一个中心话的权限系统,决定谁可以访问哪些服务。

而OAuth允许这些权限控制传达到用户手里,由用户最终确定是否允许该次访问。

这个让我想起有点像手机登录,网站上点击按钮,在电脑上点击登录。

 

OAuth系统通常追随TOFU原则:Trust On First Use

TOFU模型中,同一个权限,如果需要用户最终确定,则只确定一次,后面默认授权

不是一定要求OAuth系统一定使用TOFU

实际中会采用三层清单机制

【进阶技术】一篇文章搞掂:OAuth2

白名单确定了已知的、良好的和可信的应用程序,以及黑名单确定已知的不良应用程序或其他负面角色。这些决定可以很容易地从最终用户手中拿出来,并根据系统策略预先决定。

在传统的安全模型中,讨论到这里就结束了,因为没有在白名单的东西肯定在黑名单上。

然而,加入TOFU后,我们可以增加一个灰色列表,基于用户的运行时决策来判断是否授权。

这些决定可以是记录和审计,并且通过策略将违反的风险最小化。

通过提供灰色列表功能,系统可以在不牺牲安全性的情况下极大地扩展其使用方式。

 

1.4、OAuth2:优点、缺点、丑陋

 OAuth 2.0非常擅长捕获用户委派决策并在整个网络中传递。

它允许多个不同方参与安全决策过程,尤其是运行时的最终用户。

这是一个协议许多不同的运动部件,但在许多方面它其它替代方案更加简单和更加安全。

 

OAuth2的一个假定条件就是,外部客户端的数量是受保护资源和验证服务器数量的几个数量级倍数

通常有一个验证服务器,可以管理多个受保护的资源,然后有很多客户端想要访问资源

OAuth2成功地将复杂性从客户端转嫁到服务器,从而使客户端变成一个最简单的系统。

OAuth2对于客户端来说,比使用帐号密码只是复杂一点点,但是在很多情况下,安全得多。

 

 

11.2 结构化的令牌:JSON Web Token(JWT)

如果我们可以创建一个令牌,而不需要对共享数据库进行查找里面有所有必要的信息吗?这样,就有了授权服务器可以通过令牌本身间接地与受保护资源通信吗网络API调用的任何使用。

使用此方法,授权服务器将打包受保护资源需要知道的任何信息,例如令牌的过期时间戳和授权它的用户。

所有这些都被发送到客户机,但是客户机不会知道这些内容,因为在所有OAuth 2.0系统中,令牌对客户机仍然是不透明的。

一旦客户端有了令牌,它会像随机blob那样将令牌发送到受保护资源。

能够理解令牌的受保护资源,解析令牌中的内容,并基于其进行授权

 

 

Spring Security OAuth2

官方文档:https://projects.spring.io/spring-security-oauth/docs/oauth2.html

官方例子: