OAuth 2是什么
OAuth 2是一个可以通过浏览器,手机等多种设备进行安全授权的一个标准简单的开源协议。
随着互联网的兴起以及普及,越来越多的应用出现在用户的面前。这些应用大部分都是相对独立的以及由不同的公司进行运营的。不同的应用也保存了不同的数据。因此跨应用的数据访问就变得不可避免。当我们需要跨应用访问数据的时候,我们就需要解决如何让应用A能够访问到应用B中的用户数据。比如说,在百度云或者OneDrive中保存了相片(应用B),相片打印服务(应用A)就需要访问百度云或者OneDrive中的数据进行处理。
一种最简单的方法就是应用A询问用户在应用B中的认证信息,然后使用这个认证信息进行数据访问。但是这样子就意味着应用A拥有了用户的认证信息,应用A可以随意访问用户在应用B中的数据(虽然每个应用都声称不会滥用,但谁知道呢)。
因此需要一种方案可以能够授权应用A适当的权限来获取应用B中的数据。而OAuth 2就是这么一种解决方案。
代客泊车钥匙的例子
计算机世界,很多时候都是现实世界的映射,OAuth 2也不例外。
在影视作品中,我们常常可以看到主角们开着车来到一个豪华的酒店或者赌场的大堂,下了车之后直接扔了一副车钥匙给服务生。服务生会替车主将车停好。如果是一辆小破车,或许车主还不至于太担心服务生把车私自开走。但是要是是一辆豪车的话,就很难说了。
那么之所以服务生没有能把车开走,秘诀就在这个车钥匙上。这个车钥匙是代客泊车专用钥匙(英文叫做valet parking key)。这钥匙只能限制性的操作车中的某些功能,比如只能以时速不超过20km/h行驶,或者不能驾驶超过10分钟,还有类似无法打开天窗和后备箱。通过这种功能性的限制(权限限制),使得服务生只能操作被允许的功能即代客泊车,而无法完成超过其权限的操作,比如拿走后备箱的东西等等。
在这个例子中,涉及到了五个部分,车主,服务生,代客泊车钥匙,车主钥匙,以及车。这五个部分对应到OAuth 2的场景中就是,资源所有者,客户终端,token,资源所有者在资源服务器上的用户名和密码,资源服务器上的资源。如果用我们上面应用A和应用B的场景,那就是服务生=应用A=客户终端,车=应用2=资源服务器上的资源。
OAuth 2 组件
在上面的例子中也简略的提到了OAuth 2的各个组件。OAuth 2中一共涉及到4个组件,客户端,用户也就是资源所有者,授权服务器,以及资源服务器。
这四个组件的大致关系如下图所示。授权服务器是一个能够提供受限的密钥(key)或者令牌(token)类似于上文提到的valet parking key。
客户端包括了可信客户端和非可信客户端。可信客户端一般是指客户端和资源服务器属于同一个团体开发的,比如微博的资源服务器和微博官方客户端。非可信客户端,则一般指由第三方开发的客户端,比如很多第三方的微博应用。
从上图的示例中可以看出,用户即资源所有者可以通过客户端访问资源服务器上的资源。客户端为了能够访问资源服务器,需要先获得一个令牌(token)。由于用户并不想直接将资源服务器的用户名密码透露给客户端,用户可以通过授权服务器给予客户端一个临时的受限访问令牌。
客户端在使用授权服务器之前必须先进行注册(一次性操作),注册的目的是让授权服务器清楚之后的授权请求是由哪个客户端发起的。同时注册的时候也会约定好之后通信所使用的密钥等信息。
客户端在完成注册之后,就可以通过下面将讲到的OAuth 2流程来获得令牌(token),然后通过令牌来访问资源服务器上的资源。
可信域
在这个授权流程中,我们还需要注意可信域,这会帮助我们后面理解为什么OAuth 2 不合适作为认证工具。可信域代表了域中组件的相互信任关系。
从下图可以看出,默认情况下,资源服务器和授权服务器属于同一个可信域。也就意味着,授权服务器知道资源服务器哪些资源需要被保护,资源服务器也知道如何验证由授权服务器产生的令牌。授权服务器和资源服务器类似于一种强耦合的关系。此外,很显然的,资源所有者和资源服务器也具有相互信任关系。
由于,上面提到的客户端可以由第三方提供,所以其不需要和授权服务器或者资源服务器属于同一个可信域。
OAuth 2 流程
由于OAuth 2可以应用在不同的客户端和场景,也就导致了OAuth 2有4种不同的流程。
前两种流程涉及到了用户的交互,需要用户进行明确的授权许可。
授权码流程(Authorization Code Flow)
使用最为广泛的一种流程,基于浏览器的访问基本都使用这种流程。
- 请求授权码
- 请求令牌
- 访问资源
简化模式(Implicit Flow)
- 请求令牌
- 访问资源
另外两种属于不需要进行任何的用户交互。
密码模式(Resource Owner Password Credential Flow)
这是类似于一些企业内部使用的授权模式。
- 使用资源所有者的用户名密码进行令牌请求
- 访问资源
客户端模式(Client Credential Flow)
这用于客户端到服务器的通信。
- 使用客户端的凭据进行令牌请求
- 访问资源
这四种模式的具体流程,我们会在之后的文章中进行详细介绍。
参考
RFC 6749 – The OAuth 2 2.0 Authorization Framework