OAuth2授权协议简介

图片来自pixabay.com的tassilo111-80733会员
[![图片来自pixabay.com的tassilo111-80733会员](http://www.hyhblog.cn/wp-content/uploads/2018/04/climber-226804_640.jpg "图片来自pixabay.com的tassilo111-80733会员")](https://pixabay.com/photo-226804/ "图片来自pixabay.com的tassilo111-80733会员")

OAuth 2.0是一个业界标准的授权协议,其定义了四种可以适用于各种应用场景的授权交互模式:授权码模式、应用授信模式、用户授信模式、简化模式。其中,授权码模式被广泛应用于第三方互联网开放平台,通过第三方登录是其最常见应用场景之一,比如使用微信、QQ和淘宝账号进行登录。

本文对OAuth2.0授权协议进行介绍和梳理,从一个简单的授权场景讲起,以了解OAuth 2.0所要解决的授权问题,然后对OAuth 2.0的四种授权交互模式进行一一介绍,最后对各个授权模式的相互关系、区别、以及如何选择进行讲解。

1. 认识OAuth 2.0

OAuth 2.0是一个业界标准的授权协议(authorization protocol),这里的授权是以委派代理(delegation)的方式。可以这样理解,OAuth 2.0提供一种协议交互框架,让某个应用能够以安全地方式获取到用户的委派书,这个委派书在OAuth 2.0中就是访问令牌(access token),随后应用便可以使用该委派书,代表用户来访问用户的相关资源。

在OAuth 2.0的协议交互中,有四个角色的定义,

  • 资源所有者(Resource Owner):顾名思义,资源的所有者,很多时候其就是我们普通的自然人(但不限于自然人,如某些应用程序也会创建资源),拥有资源的所有权。
  • 资源服务器(Resource Server):保存着受保护的用户资源。
  • 应用程序(Client):准备访问用户资源的应用程序,其可能是一个web应用,或是一个后端web服务应用,或是一个移动端应用,也或是一个桌面可执行程序。
  • 授权服务器(Authorization Server):授权服务器,在获取用户的同意授权后,颁发访问令牌给应用程序,以便其获取用户资源。

2. 从一个简单的应用场景谈起

为了方便讨论,我们假设有一个用户Michael,他在一个资源服务器上保存着他自己的账号信息,例如微信账号的姓名、头像等。某个应用程序在用户登录时,需要获取Michael的这些账号信息。

Michael在资源服务器上保存的账号信息是受保护的,为了让应用程序能够获取Michael的账号信息,需要提供用户的访问密码。有一个简单的方法是,在应用服务器和资源服务器之间共享同一访问密码,当Michael登录输入密码后,应用程序复制Michael的登录密码并向资源服务器请求访问,获取Michael的账号信息。这是早些时候比较常见的跨应用授权访问方法。

这样子做有很大的安全隐患,主要有如下三个方面的问题,

  1. 用户在应用程序和资源服务器需要保持一致的密码
  2. 无法控制应用程序的权限,应用程序需要的是读权限,但是拿到用户密码后,获取到的却是用户的所有访问权限
  3. 用户的密码会被应用程序获取到,有用户密码泄露的风险,一旦应用程序多了,安全风险不可控

在简单的应用场景里,在应用程序和资源服务器之间保持一致的密码是可行的,这也确实能够带来一定的便利,至少用户不用记多套用户名和密码,但账号和密码的独立性无法得到保证,应用程序可以直接接触到用户密码等敏感信息,账号的安全性也无法控制。

为了解决第1个问题,用户Michael在应用程序和资源服务器可以使用不同的密码登录,有一个可行的方法是,让用户输入两次密码,第一次输入密码为了登录应用程序,第二次让Michael输入其在资源服务器的登录密码,以便应用程序获取资源服务器的账号信息。

这样就需要用户输入两次密码,给用户的使用带来很大的不便,而且这个方案依然存在第2和第3的问题。

为了解决第2个问题,限制应用程序访问资源服务器的权限,我们可以让用户在资源服务器申请一个只读的受限密码,该受限密码只用来读取用户信息,无法用来进行编辑和删除操作,用户输入这个只读密码给应用程序,让应用程序读取用户在资源服务器上的信息。

该方法解决第2个问题,但再次增加了用户的不便,使得用户不得不面对复杂的密码管理,用户不得不在资源服务器上维护两个密码,一个正常使用的密码和一个只读的受限密码,并且该方法依然没有解决第3个问题。

为了解决第3个问题,让应用程序不再接触用户在资源服务器的密码,一个可行的办法是,资源服务器直接颁发给应用程序一个读权限的key,应用程序拿着这个key去读取资源服务器的所有用户的信息。

这个方法解决了上述提到的第3个问题,但是这个key是一个通用的读权限,权限范围很大,其和用户没有任何关联。在很多时候,我们还是需要用户级别上的受限权限控制。

能否有一个方案,在不影响用户的使用便利性,并且颁发一个在用户级别上的可控权限key?可以考虑的是,用户动态按需地向资源服务器申请读权限key,然后颁发给应用程序,用于应用程序去申请访问用户的信息,该受限密码在颁发后有一定的时效性,甚至可以指定其只能被使用一次。这样子的话,解决问题1、2和3的条件都得到满足。

这个方案已经很接近于OAuth 2.0在设计之初所提供的授权方案,不一样之处的是,受限密码的颁发交给了独立的安全组件:授权服务器。

这里马上就要介绍OAuth 2.0的基本授权方式:授权码模式。

3. OAuth 2.0基本授权流程:授权码模式

让我们看看在增加授权服务器之后,OAuth 2.0的一个基本授权流程,

如图所示,授权流程场景可以描述为如下几个步骤,

  1. 用户在应用程序中,应用程序尝试获取用户保存在资源服务器上的信息,比如用户的身份信息和头像,应用程序首先让重定向用户到授权服务器,告知申请资源的读权限,并提供自己的client id。
  2. 到授权服务器,用户输入用户名和密码,服务器对其认证成功后,提示用户即将要颁发一个读权限给应用程序,在用户确认后,授权服务器颁发一个授权码(authorization code)并重定向用户回到应用程序。
  3. 应用程序获取到授权码之后,使用这个授权码和自己的client id/secret向认证服务器申请访问令牌/刷新令牌(access token/refresh token)。授权服务器对这些信息进行校验,如果一切OK,则颁发给应用程序访问令牌/刷新令牌。
  4. 应用程序在拿到访问令牌之后,向资源服务器申请用户的资源信息
  5. 资源服务器在获取到访问令牌后,对令牌进行解析(如果令牌已加密,则需要进行使用相应算法进行解密)并校验,并向授权服务器校验其合法性,如果一起OK,则返回应用程序所需要的资源信息。

这个授权流程在OAuth 2中被称为授权码模式(authorization code grant),其命名的原因是,应用程序使用授权码来向授权服务器申请访问令牌/刷新令牌。

可以看到,在整个过程中应用程序没有接触到用户的密码。

授权码和令牌都是一个唯一标识的值,其各个意义为,

  • 授权码:即用户的委派书,代表着用户的受限权限,有时效性
  • 访问令牌:用于应用程序每次向资源服务器访问时提供,有时效性,如果安全性比较高的话,则每个访问令牌可以被设置为只用一次,或者对令牌设置一个有效期,在有效期可以反复使用。
  • 刷新令牌:用于应用程序向授权服务器申请新的访问令牌,在访问令牌失效或过期的时候,重新获取新的访问令牌。

注意的是,访问令牌对于应用程序来说是透明的,应用程序无需关注访问令牌所带的任何信息,只需在访问资源服务器时带上它。但是资源服务器需要知道访问令牌的组成和加密方式,资源服务器需要解析或解密这个访问令牌,查看并校验里面的信息。

授权服务器和访问令牌,前者为授权的颁发,后者为授权的载体,两者实现了动态按需地代理权限分发,这也是OAuth 2.0解决方案在授权上所带来的创新变化。

4. OAuth 2.0授权服务的EndPoint交互

若要了解OAuth 2.0的整个授权交互,则需要对授权服务器所提供的四个重要授权Endpoint进行了解,

  • /authorize:主要用于颁发授权码,在特殊场景下也可直接颁发访问令牌(这里的特殊场景是指简化模式,详情见后面讨论)
  • /token:用于颁发访问令牌和刷新令牌
  • /introspect:检查令牌的合法性
  • /revoke:吊销令牌

在基本授权码模式下,授权服务器上发生的EndPoint交互流程如下,

| 授权服务器
EndPoint | 授权码模式 | 请求结果 |
| :---: | :----------- | :---: |
| /authorize | GET /authorize?response_type=code&scope=read&client_id=id&redirect_uri&state=xxx HTTP/1.1
Host: localhost | 授权码 |
| /token | POST /token HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=code&redirect_uri=uri | 访问令牌/刷新令牌 |
| /introspect | POST /introspect HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

token=123 | 检查令牌 |
| /revoke | POST /revoke HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Authorization: Basic (client id+secret)

token=123 | 吊销令牌 |

授权服务器
EndPoint
授权码模式 请求结果
/authorize GET /authorize?response_type=code&scope=read&client_id=id&redirect_uri&state=xxx HTTP/1.1
Host: localhost
授权码
/token POST /token HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=code&redirect_uri=uri

访问令牌/刷新令牌
/introspect POST /introspect HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

token=123

检查令牌
/revoke POST /revoke HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Authorization: Basic (client id+secret)

token=123

吊销令牌

5. OAuth 2.0其它授权模式及应用场景

上面讲的OAuth 2.0基本授权方式适用于资源所有者和应用程序两个角色都存在的场景下,在现实世界中,往往资源所有者和应用程序两个角色有缺失或者合二为一了,OAuth 2针对实际的应用场景中提供了不同的授权方式。

5.1 Implicit Grant:简化模式

有一种场景需求是这样子的,应用程序运行在用户端,换句话说在网络拓扑上应用程序这个和资源所有者两个角色是合在了一起,比如浏览器JS应用程序(In-Browser JavaScript App)就是这样子的应用场景。

如下图所示,

应用程序运行在客户端,一个最大的变化就是其变成了公开应用程序(Public Client),应用程序的运行完全暴露在用户的控制之中。在这种场景下,应用程序是无法隐藏自己的一些敏感数据,比如client secret和授权码,在这个方式下,再向授权服务器获取授权码是多此一举。为此OAuth 2.0提供简化模式,授权服务器在校验好用户信息后,直接颁发给应用程序访问资源服务器的访问令牌。换句话说,应用程序在获取访问令牌时无需提供授权码和client secret。

这个授权模式被称为简化模式,其命名的原因主要是由于跳过获取授权码这一中间过程,无需授权码而可以直接获取访问令牌。

整个授权流程如下,

  1. 用户在应用程序中,应用程序尝试获取用户保存在资源服务器上的信息,比如用户的身份信息和头像,应用程序首先让用户重定向到授权服务器,告知申请资源的读权限,并提供自己的client id。在重定向的过程中,应用程序指定使用Implicit Grant授权方式。
  2. 在授权服务器,用户输入用户名和密码,服务器对其认证成功后,提示用户即将要颁发一个读权限给应用程序,在用户确认后,授权服务器直接颁发一个访问令牌并重定向用户回到应用程序。
  3. 应用程序在拿到访问令牌之后,向资源服务器申请用户的资源信息
  4. 资源服务器在获取到访问令牌后,对令牌进行解析(如果令牌已加密,则需要进行使用相应算法进行解密)并校验,并向授权服务器校验其合法性,如果一起OK,则返回应用程序所需要的资源信息。

可以看到在简化模式和标准的授权码模式相比,其流程交互简化了很多,但安全性也是随之降低,在使用简化模式时,需要考虑安全性降低带来的应用使用问题,因此,应该尽量在这种模式下提供对安全度要求不高的操作,例如只读操作。

另外需要注意的是,应用程序从授权服务器获取到了访问令牌,但不需要获取刷新令牌,这是由于在这种使用场景下,用户应该是一直在场,一旦访问令牌过期,只要让用户重新登录一下即可,无需使用刷新令牌来定期更新访问令牌。另外对于浏览器JS应用程序,整个会话(session)一般也是短期,不用考虑长时间下使用时令牌刷新机制。

我们看下在简化模式下,授权服务器上EndPoint发生的交互流程,

| 授权服务器
EndPoint | 简化模式 | 请求结果 |
| :---: | :----------- | :---: |
| /authorize | GET /authorize?response_type=token&scope=read&client_id=xyz&redirect_uri=uri&state=guid HTTP/1.1
Host: localhost | 访问令牌 |
| /token | 无 | 无 |
| /introspect | 见授权码模式 | 检查令牌 |
| /revoke | 见授权码模式 | 吊销令牌 |
授权服务器
EndPoint
简化模式 请求结果
/authorize GET /authorize?response_type=token&scope=read&client_id=xyz&redirect_uri=uri&state=guid HTTP/1.1
Host: localhost
访问令牌
/token
/introspect 见授权码模式 检查令牌
/revoke 见授权码模式 吊销令牌

5.2 Client Credentials Grant:应用授信模式

应用授信模式主要解决的是在如下两种情况下,

  • 资源所有者角色不参与授权交互
  • 应用程序角色本身就是资源所有者

如何获取访问令牌的问题。

如下图所示,

整个流程如下,

  1. 应用程序尝试获取在资源服务器上的信息,应用程序直接向授权服务器申请访问令牌,告知申请资源的读权限,并提供自己的授信凭证(client id/secret)。在申请请求中,应用程序指定使用client credentials授权方式。在授权服务器,服务器对其client credentials校验成功后,授权服务器直接颁发一个访问令牌给应用程序。
  2. 应用程序在拿到访问令牌之后,向资源服务器申请用户的资源信息
  3. 资源服务器在获取到访问令牌后,对令牌进行解析(如果令牌已加密,则需要进行使用相应算法进行解密)并校验,并向授权服务器校验其合法性,如果一起OK,则返回应用程序所需要的资源信息。

这个授权流程被称为应用授信模式,其命名原因是由于应用程序是通过自己的授信凭证(client id/secret)直接向授权服务器申请访问令牌。这种模式一般用在可信的应用程序。

和简化模式一样,授权服务器无需颁发刷新令牌给应用程序,原因很简单,应用程序想要的话,直接再调用授权服务器一次即可。

我们看下在应用授信模式下,授权服务器上EndPoint发生的交互流程,

| 授权服务器
EndPoint | 应用授信模式 | 请求结果 |
| :---: | :----------- | :---: |
| /authorize | 无调用 | |
| /token | POST /token HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=read | 访问令牌 |
| /introspect | 见授权码模式 | 检查令牌 |
| /revoke | 见授权码模式 | 吊销令牌 |

授权服务器
EndPoint
应用授信模式 请求结果
/authorize 无调用
/token POST /token HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=read

访问令牌
/introspect 见授权码模式 检查令牌
/revoke 见授权码模式 吊销令牌

5.3 Resource Owner Credentials Grant:用户授信模式

在基本的授权码模式中,用户需要跳转到授权服务器上,使用用户名和密码登录后拿到授权码,然后把授权码交给应用程序,然后再去申请访问令牌。但有些时候,能否省去这个来回的跳转过程,把用户名和密码直接交给应用程序,让应用程序去申请访问令牌。

这个就是用户授信模式的应用场景,这个场景其实回到了本文中最先提到的授权使用场景,应用程序有接触到用户的用户名和密码,因此,应用程序必须是完全可信的。

整个流程如下,

  1. 用户在应用程序中,应用程序首先让用户到登录页面输入用户名和密码。
  2. 应用程序拿到资源所有者的用户名和密码,加上自己的client id/secret一同向认证服务器申请访问令牌/刷新令牌。授权服务器对这些信息进行校验,如果一切OK,则颁发给应用程序访问令牌/刷新令牌。
  3. 应用程序在拿到访问令牌/刷新令牌之后,向资源服务器申请用户的资源信息。
  4. 资源服务器在获取到访问令牌后,对令牌进行解析(如果令牌已加密,则需要进行使用相应算法进行解密)并校验,并向授权服务器校验其合法性,如果一起OK,则返回应用程序所需要的资源信息。

这个授权流程被称为用户授信模式,其命名原因是由于应用程序是通过用户的授信凭证(比如:用户名和密码)向授权服务器申请访问令牌。

当应用程序换取到访问令牌之后,从安全的角度考虑,应用程序应该立即删除用户的授信凭证,不再保留。这也是OAuth 2.0所建议的安全规范,应用程序不应该通过用户的用户名和密码,而是应该都通过访问令牌去访问资源。

我们看下在用户授信模式下,授权服务器上EndPoint发生的交互流程,

| 授权服务器
EndPoint | 用户授信模式 | 请求结果 |
| :---: | :----------- | :---: |
| /authorize | 无调用 | |
| /token | POST /token HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

grant_type=password &scope=read&username=Michael&password=secret | 获取到访问令牌和刷新令牌 |
| /introspect | 见授权码模式 | 检查令牌 |
| /revoke | 见授权码模式 | 吊销令牌 |

授权服务器
EndPoint
用户授信模式 请求结果
/authorize 无调用
/token POST /token HTTP/1.1
Host: localhost
Authorization: Basic (client id+secret)
Content-Type: application/x-www-form-urlencoded

grant_type=password &scope=read&username=Michael&password=secret

获取到访问令牌和刷新令牌
/introspect 见授权码模式 检查令牌
/revoke 见授权码模式 吊销令牌

6. 四种授权模式的联系和区别

OAuth 2.0的四种授权模式,有一定的联系,也有区别。前文也对这些联系和区别做了一些描述,这里做下小结。

无论哪种授权模式,都是以获取访问令牌为目的,访问令牌是各个授权模式交互的最终结果。

我们先比较下各个模式获取访问令牌的手段,

  • 授权码模式:授权码+应用的授信凭据
  • 简化模式:应用client id + 用户的授信凭据
  • 应用授信模式:应用的授信凭据
  • 用户授信模式:应用的授信凭据+用户的授信凭据

上面说的,应用的授信凭据是指client id和secret,用户的授信凭据则一般是用户名和密码。

这四种授权模式中,授权码模式是基本的授权模式,

  1. 授权码模式:基本授权模式,它需要有四个角色同时在场才能完成授权:资源所有者、应用程序、授权服务器、资源服务器。

其它三种模式可以在其基本的授权码模式上演绎出来,

  1. 简化模式:开放应用程序,应用程序运行在公开开放的环境。即:无需应用程序的认证。
  2. 应用授信模式:应用程序即为资源所有者,或资源所有者不参与授权交互。即:无资源所有者的认证。
  3. 用户授信模式:无授权码的颁发过程,直接通过用户名和密码换取授权。

下图给出了演绎过程,

下表列出四种授权模式在授权服务器上/authorize和/token两个Endpoint的交互结果,

授权服务器
EndPoint
授权码
模式
简化
模式
应用授信
模式
用户授信
模式
/authorize 授权码 访问令牌
/token 访问令牌+刷新令牌 访问令牌 访问令牌+刷新令牌
最终结果 访问令牌+刷新令牌 访问令牌 访问令牌 访问令牌+刷新令牌

表中无的含义是指无交互。各个模式和Endpoint的更详细交互信息参见上文。

7. 四种授权模式的时序图

下图为四种授权模式在各个角色上的流转时序图,主要包括token的颁发和使用流程。

更清晰的时序图,见点击这里查看。

8. 如何选择合适OAuth 2.0授权方式

面对四种授权方式,在了解OAuth 2.0四个角色和流程后,接下来就是为自己的应用场景选择一种授权模式。

简单的话,可以根据下面的流程图来进行参考选择,

原图自Alex Bilbie的A Guid To OAuth 2.0 Grants

图中各个概念的定义说明如下,

  1. 资源所有者
    • 自然人用户:资源所有者是我们普通的自然人。
    • 应用程序:是指当资源的所有者不是我们普通的自然人,而是应用程序,也就是机器。
  2. 应用程序类型
    • Web应用:运行在后端web服务器上的应用
    • 基于user-agent的应用:运行在浏览器JS应用
    • 原生应用:桌面应用,移动应用(安卓和iOS应用)
  3. 第一方和第三方应用
    • 第一方应用:指可信赖的应用,其可以接触用户的密码等敏感信息,应用安全可靠。
    • 第三方应用:指由第三方开发的应用,其安全性不受自己控制,需将用户的密码等敏感信息和第三方应用隔离开,颁发令牌给第三方应用,第三方应用凭借令牌访问资源。

9. OAuth 2的安全威胁和考虑

在使用OAuth 2之前,有必要了解下OAuth在安全性方面的考虑和注意点,比如在授权endpoints上需配置HTTPS,比如为了防止client受到CSRF攻击,可以在重定向时添加一个state标记位,授权服务器在跳转回到client时会带回这个state,由client校验该标记位,确认为当前请求为前一个跳转的合法回调,以避免被非法者冒用,等等。

可以通过阅读文档RFC6749和RFC6819来获取更多详细资料,

  1. RFC6749:The OAuth 2.0 Authorization Framework中第10章节对Security Considerations的描述
  2. RFC6819:OAuth 2.0 Threat Model and Security Considerations

OAuth 2.0的更多RFC文档列举如下,以便扩展阅读,

  1. RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage
  2. RFC 7009 - OAuth 2.0 Token Revocation
  3. RFC 7521 - Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
  4. RFC 7522 - Security Assertion Markup Language (SAML) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants
  5. RFC 7523 - JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
  6. RFC 7591 - OAuth 2.0 Dynamic Client Registration Protocol
  7. RFC 7592 - OAuth 2.0 Dynamic Client Registration Management Protocol
  8. RFC 7628 - A Set of Simple Authentication and Security Layer (SASL) Mechanisms for OAuth
  9. RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients
  10. RFC 7662 - OAuth 2.0 Token Introspection

10. 文中讨论的术语(中英文对照)

  • 授权协议(authorization protocol)
  • 委派代理(delegation)
  • 资源所有者(resource owner)
  • 资源服务器(resource server)
  • 应用程序(client)
  • 授权服务器(authorization server)
  • 访问令牌(access token)
  • 刷新令牌(refresh token)
  • 授权码(authorization code)
  • 开放应用程序(public client)
  • 私有应用程序(private client)
  • 授权码模式(authorization code grant)
  • 简单模式(implicit grant)
  • 应用授信模式(client credentials grant)
  • 用户授信模式(resource owner credentials grant)
  • 浏览器JS应用(in-browser JavaScript app)
  • 会话(session)

11. 参考资料

  1. 《OAuth 2 in Action》,作者Justin Richer,Antonio Sanso
  2. RFC6749:The OAuth 2.0 Authorization Framework
  3. Alex Bilbie的博文:A Guide To OAuth 2.0 Grants

认证、授权、鉴权和权限控制

图片来自pixabay.com的fcja99-5064003会员

本文将对信息安全领域中认证、授权、鉴权和权限控制这四个概念给出相应的定义,并对这个概念之间的相互关系进行梳理。本文给出的概念定义将有助于后续文章中对互联网应用开发用户登录功能的更多讨论。

注:本文讨论的互联网应用开发,主要是指web应用和移动应用的开发。

1. 认证

认证是指根据声明者所特有的识别信息,确认声明者的身份。认证在英文中对应于identification这个单词。

最常见的认证实现方式是通过用户名和密码,但认证方式不限于此。下面都是当前常见到的认证技术,

  • 身份证
  • 用户名和密码
  • 用户手机:手机短信、手机二维码扫描、手势密码
  • 用户的电子邮箱
  • 基于时间序列和用户相关的一次性口令
  • 用户的生物学特征:指纹、语音、眼睛虹膜
  • 用户的大数据识别
  • 等等

为了确认用户的身份,防止伪造,在安全要求高的场合,经常会使用组合认证(或者叫多因素认证),也就是同时使用多个认证方式对用户的身份进行校验。

2. 授权

简单来说,授权一般是指获取用户的委派权限。在英文中对应于authorization这个单词。

在信息安全领域,授权是指资源所有者委派执行者,赋予执行者指定范围的资源操作权限,以便执行者代理执行对资源的相关操作。这里面包含有如下四个重要概念,

  • 资源所有者,拥有资源的所有权利,一般就是资源的拥有者。
  • 资源执行者,被委派去执行资源的相关操作。
  • 操作权限,可以对资源进行的某种操作。
  • 资源,有价值的信息或数据等,受到安全保护。

需要说明的是,资源所有者和执行者可以是自然人,就是普通用户,但不限于自然人。在信息安全领域,资源所有者和执行者,很多时候是应用程序或者机器。比如用户在浏览器上登录一个网站,那么这个浏览器就成为一个执行者,它在用户登录后获取了用户的授权,代表着用户执行各种指令,进行购物、下单、付钱、转账等等操作。

同时,资源所有者和执行者可以是分开的不同实体,也可以是同一个。若是分开的两者,则资源执行者是以资源所有者的代理形式而存在。

授权的实现方式非常多也很广泛,我们常见的银行卡、门禁卡、钥匙、公证书,这些都是现实生活中授权的实现方式。其实现方式主要通过一个共信的媒介完成,这个媒介不可被篡改,不可随意伪造,很多时候需要受保护,防止被窃取。

在互联网应用开发领域,授权所用到的授信媒介主要包括如下几种,

  • 通过web服务器的session机制,一个访问会话保持着用户的授权信息
  • 通过web浏览器的cookie机制,一个网站的cookie保持着用户的授权信息
  • 颁发授权令牌(token),一个合法有效的令牌中保持着用户的授权信息

前面两者常见于web开发,需要有浏览器的支持。

3. 鉴权

鉴权是指对于一个声明者所声明的身份权利,对其所声明的真实性进行鉴别确认的过程。在英文中对应于authentication这个单词。

鉴权主要是对声明者所声明的真实性进行校验。若从授权出发,则会更加容易理解鉴权。授权和鉴权是两个上下游相匹配的关系,先授权,后鉴权。授权和鉴权两个词中的“权”,是同一个概念,就是所委派的权利,在实现上即为授信媒介的表达形式。

因此,鉴权的实现方式是和授权方式有一一对应关系。对授权所颁发授信媒介进行解析,确认其真实性。下面是鉴权的一些实现方式,

  • 门禁卡:通过门禁卡识别器
  • 钥匙:通过相匹配的锁
  • 银行卡:通过银行卡识别器
  • 互联网web开发领域的session/cookie/token:校验session/cookie/token的合法性和有效性

鉴权是一个承上启下的一个环节,上游它接受授权的输出,校验其真实性后,然后获取权限(permission),这个将会为下一步的权限控制做好准备。

4. 权限控制

权限控制是指对可执行的各种操作组合配置为权限列表,然后根据执行者的权限,若其操作在权限范围内,则允许执行,否则禁止。权限控制在英文中对应于access/permission control。

对于权限控制,可以分为两部分进行理解:一个是权限,另一个是控制。权限是抽象的逻辑概念,而控制是具体的实现方式。

先看权限(Permission),这是一个抽象的概念,一般预先定义和配置好,以便控制的具体实现。权限的定义,若简单点,可以直接对应于一个可执行的操作集合。而一般情况下,会有基于角色的方式来定义权限,由角色来封装可执行的操作集合。

若以门禁卡的权限实现为例,上述两种定义方式则可以各自表达为,

  • 这是一个门禁卡,拥有开公司所有的门的权限
  • 这是一个门禁卡,拥有管理员角色的权限,因而可以开公司所有的门

可以看到,权限作为一个抽象的概念,将执行者和可具体执行的操作相分离。

在上文的讨论中,鉴权的输出是权限(Permission)。一旦有了权限,便知道了可执行的操作,接下来就是控制的事情了。

对于控制,是根据执行者的权限,对其所执行的操作进行判断,决定允许或禁止当前操作的执行。现实生活中控制的实现方式,多种多样,

  • 门禁:控制门的开关
  • 自行车锁:控制车轮
  • 互联网web后端服务:控制接口访问,允许或拒绝访问请求

5. 认证、授权、鉴权和权限控制的关系

认证、授权、鉴权和权限控制这四个环节是一个前后依次发生、上下游的关系,

认证-->授权-->鉴权-->权限控制

需要说明的是,这四个环节在有些时候会同时发生。 例如在下面的几个场景,

  • 使用门禁卡开门:认证、授权、鉴权、权限控制四个环节一气呵成,在瞬间同时发生
  • 用户的网站登录:用户在使用用户名和密码进行登录时,认证和授权两个环节一同完成,而鉴权和权限控制则发生在后续的请求访问中,比如在选购物品或支付时。

无论怎样,若从时间顺序方面来看,这四个环节是按时间前后、依次相继发生的关系。

6. 认证和鉴权的关系

这两个概念在很多时候是被混淆最多的概念。被混淆的主要原因,如上文所述,很多时候认证、授权、鉴权和权限控制一同发生,以至于被误解为,认证就是鉴权,鉴权就是认证。

其实两者是不一样的概念,两者都有对身份的确认过程,但是两者的主要区别在于,

  • 认证是确认声明者的本身身份,其作为授权的上游衔接而存在
  • 鉴权是对声明者所声明的真实性进行确认的过程,其作为授权的下游衔接而存在

7. 小结

下面对本文讨论的四个概念用一个表格进行小结,

定义 英文 实现方式
认证 确认声明者的身份 identification 根据声明者独特的识别信息
授权 获取用户的委派权限 authorization 颁发一个授信媒介,不可被篡改,不可伪造,受保护
鉴权 对所声明的权限真实性进行鉴别的过程权限是一个抽象的逻辑概念,定义和配置可执行的操作,而控制是具体的实现方式,通过一定的方式控制操作的允许和禁止 authentication 鉴权和授权是一一对应关系,解析授信媒介,确认其合法性、有效性
权限控制 权限是一个抽象的逻辑概念,定义和配置可执行的操作,而控制是具体的实现方式,通过一定的方式控制操作的允许和禁止 access/permission control 实现方式多样,根据具体情况来实现。

8. 参考文献

  1. 维基百科wiki - Identification
  2. 维基百科wiki - Authorization
  3. 维基百科wiki - Authentication
  4. 维基百科wiki – Access Control

互联网应用开发的用户登录

图片来自pixabay.com的Pexels-2286921会员

在互联网应用开发中,用户登录是一个必要的安全组件,其涉及到认证、授权、鉴权和权限控制等各个安全环节,在实际的应用场景中有单点登录的需求。为了更加全面的介绍互联网应用开发的用户登录技术,下面将分三篇独立的文章对相关的概念和架构实现进行梳理介绍。

注:本文讨论的互联网应用开发,主要是指web应用和移动应用的开发。

1. 认证、授权、鉴权和权限控制

介绍这四个概念的定义及其之间相互关系。

请点击这里查看。

2. 单点登录的通用架构实现

单点登录(single sign on)也被称为统一登录,它不仅仅是一个用户登录功能模块,它更是一种完整的技术架构方案,提供统一的认证、授权、鉴权和权限控制功能,方便用户的使用,以及应用的开发接入。

本文将对单点登录的通用技术架构进行介绍,主要分为第一方登录、第三方登录、分布式和集中式权限控制等这四大方面的架构实现。

请点击这里查看。

3. OAuth 2.0授权协议简介

作为一种授权代理协议,OAuth 2.0被广泛用于第三方开发平台中,尤其是第三方登录的应用场景。本文将详细介绍OAuth 2.0授权协议的四种授权模式,以及各个模式的应用场景、联系和区别,最后介绍在实践中如何选择合适的授权模式。

请点击这里查看。