OAuth2 协议详解

OAuth2 (Open Authorization 2) 是一种授权协议,它允许用户授权第三方应用程序代表用户访问受保护的资源。

1 OAuth2 协议的应用场景

OAuth2 协议可以应用于许多场景,包括以下几个主要方面:

  • 第三方应用程序的授权访问: OAuth2 协议最常见的应用场景是允许第三方应用程序代表用户访问受保护的资源。例如,社交媒体网站允许用户使用他们的账号登录第三方应用程序,如游戏、新闻应用等。用户可以授权第三方应用程序使用他们的社交媒体账号信息,以便他们可以访问受保护的资源(如用户资料、好友列表等)。
  • API 访问授权: OAuth2 协议还可以用于授权访问 API。例如,某些公司的 API 需要授权才能访问,开发者需要使用他们的客户端 ID 和密钥来获得访问令牌,并使用该访问令牌来访问 API。
  • 移动应用程序访问:OAuth2 协议也可以用于移动应用程序访问 API 和其他受保护的资源。移动应用程序可以使用 OAuth2 协议向授权服务器请求访问令牌,并使用该访问令牌来访问受保护的资源。
  • 企业级应用程序访问:OAuth2 协议可以用于授权企业级应用程序访问受保护的资源。例如,企业级应用程序可以使用 OAuth2 协议请求访问令牌,并使用该访问令牌来访问企业数据和其他资源。

2 OAuth2 协议的角色

OAuth2 协议中定义了四个核心的角色:资源拥有者、客户端、授权服务器和资源服务器

OAuth2 协议的角色
  • 资源拥有者:资源拥有者是指拥有受保护资源的用户。资源拥有者可以是个人或组织。

    在 OAuth2 协议中,资源拥有者通过授权服务器授权客户端访问受保护资源。资源拥有者可以使用用户名和密码、生物识别信息或其他方法验证他们的身份。

  • 客户端:客户端是指要访问受保护资源的第三方应用程序。

    在 OAuth2 协议中:

    • 客户端必须先向资源拥有者请求授权,然后使用授权令牌访问受保护资源。
    • 客户端必须在授权服务器上注册,并获得客户端 ID 和密钥。客户端使用客户端 ID 和密钥来请求访问令牌。
  • 授权服务器:授权服务器是验证并授权客户端访问受保护资源的服务器。在 OAuth2 协议中,授权服务器负责颁发访问令牌。

    授权服务器会验证客户端身份,并验证资源拥有者的授权请求。如果授权服务器认为请求有效,则授权服务器将颁发访问令牌。

  • 资源服务器:资源服务器存储受保护的资源,并验证客户端请求中的访问令牌,以确保只有受到授权的客户端才能访问受保护资源。

    如果客户端请求中包含有效的访问令牌,则资源服务器会提供受保护的资源。否则,资源服务器会拒绝客户端请求。

3 OAuth2 协议的授权模式

OAuth2 协议定义了多种授权模式,也称为授权类型,以满足不同应用场景的需求。以下是 OAuth2 协议支持的常用授权模式:

  • 授权码模式 (Authorization Code Grant):授权码模式是最常用的授权模式之一,它通过将授权码作为一次性 Token 来交换访问令牌。此模式适用于客户端能够安全存储客户端 ID 和客户端密钥的情况。

    OAuth2 Token 简介

    在 OAuth2 协议中,Token 是用于访问受保护资源的字符串。OAuth2 协议中使用两种类型的 Token:访问令牌 (Access Token) 和刷新令牌 (Refresh Token)。

    • 访问令牌 (Access Token):访问令牌是一种临时凭证,用于访问受保护资源。客户端使用访问令牌向资源服务器请求受保护资源。访问令牌通常具有较短的生命周期,例如 1 小时或更短的时间。在 OAuth2 协议中,访问令牌通常使用 Bearer Token 格式。
    • 刷新令牌 (Refresh Token):刷新令牌是一种长期凭证,用于获取新的访问令牌。当访问令牌过期时,客户端可以使用刷新令牌向授权服务器请求新的访问令牌。刷新令牌通常具有更长的生命周期,例如 30 天或更长时间。在 OAuth2 协议中,刷新令牌通常使用 JWT 格式。

    使用 Token 的好处是:

    • 安全性:Token 包含了客户端身份验证信息和访问授权信息,使得第三方应用程序无法获取资源拥有者的凭证信息。Token 只用于访问受保护的资源,并且具有有效期限,可以减少 Token 被恶意使用的风险。
    • 隔离性:每个客户端都有自己的访问令牌和刷新令牌。这使得客户端之间的访问和授权相互隔离,提高了系统的安全性。
    • 灵活性:Token 可以被任何客户端使用,而不必关心如何实现身份验证和授权。客户端只需要使用 Token 来访问受保护资源即可。

    如下所示就是一种常见的令牌信息:

    1
    2
    3
    4
    5
    6
    7
    
    {
        "access_token": "eae180c4-3674-41cc-a1b8-ea3275d05c3c",
        "token_type": "bearer",
        "refresh_token": "1da1b40b-6f27-4557-a852-c990d370512a",
        "expires_in": 43199,
        "scope": "webclient"
    }
    • access_token:代表 OAuth2 的令牌,当访问每个受保护的资源时,用户都需要携带这个令牌以便进行验证。
    • token_type:代表令牌类型,OAuth2 协议中有多种可选的令牌类型,包括 Bearer 类型、MAC 类型等:
      • Bearer Token:Bearer Token 是 OAuth2 协议中最常见的 token_type 值。它指示客户端在请求受保护的资源时,将访问令牌放在 HTTP 请求的 Authorization 请求头中,并使用 "Bearer " 作为前缀,例如:"Authorization: Bearer <access_token>"。Bearer Token 是一种无状态 Token,客户端不需要在请求中提供其他证书信息。
      • MAC Token:MAC Token 是一种安全的访问令牌类型,它使用 Message Authentication Code (MAC) 算法来签署请求,以确保请求的完整性和机密性。MAC Token 通常用于访问需要更高安全级别的受保护资源,例如金融数据或医疗记录。MAC Token 是一种有状态 Token,客户端需要在请求中提供附加的证书信息。
    • expires_in:用于指定 access_token 的有效时间,当超过这个有效时间,access_token 将会自动失效。
    • refresh_token:其作用在于当 access_token 过期后,重新下发一个新的 access_token
    • scope:指定了可访问的权限范围,这里指定的是访问 Web 资源的 “webclient”。
  • 简化模式 (Implicit Grant):简化模式适用于无法安全存储客户端 ID 和客户端密钥的客户端,例如 JavaScript 单页应用程序。该模式将访问令牌直接传递给客户端,不需要交换授权码。

  • 密码模式 (Resource Owner Password Credentials Grant):密码模式适用于可信的客户端,如移动应用程序或基于浏览器的应用程序。该模式使用用户的用户名和密码来直接获取访问令牌。

  • 客户端凭证模式 (Client Credentials Grant):客户端凭证模式适用于客户端需要访问自己的资源,而不是代表用户访问资源的情况。该模式使用客户端 ID 和客户端密钥来获取访问令牌。

  • 设备授权模式 (Device Authorization Grant):设备授权模式适用于无法直接与浏览器交互的设备,例如电视或 IoT 设备。该模式使用设备代码和用户代码来授权设备,并允许用户在另一设备上进行授权。

3.1 授权码模式授权流程

我们首先看下具代表性的授权码模式的授权流程:在用户同意授权后,授权服务器只会返回授权码而非最终的访问令牌。因此,在这种授权模式下,客户端需要通过携带授权码与授权服务器进行交互,以获得访问令牌。这就要求客户端必须具备与授权服务器直接交互的后台服务。

授权码模式授权流程

首先,当用户访问客户端时,客户端会将用户导向授权服务器,并请求用户进行授权。一旦用户同意授权,授权服务器会调用客户端的后台服务提供的回调地址,并返回一个授权码。客户端随后使用该授权码向授权服务器申请访问令牌。最后,授权服务器验证授权码并向客户端发送访问令牌。

需要注意的是,通过授权码向授权服务器申请访问令牌的过程是系统自动完成的,不需要用户参与。用户只需在流程启动阶段同意授权即可。

3.2 密码模式授权流程

接下来,我们再来看另一种比较常用的密码模式,其授权流程如下图所示:

密码模式授权流程

显然,密码模式相对简单,更容易理解。用户只需要提供自己的用户名和密码,客户端就可以使用这些信息向授权服务器请求访问令牌。授权服务器在成功验证用户身份后将会颁发令牌。

OAuth2 中的客户端模式和简化模式因为在日常开发过程中应用得不是很多,这里就不详细介绍了。