微服务中常见的认证方式详解

本文将介绍几种常见的微服务认证方式,帮助你在设计和实现微服务系统时选择合适的认证方案。

版权声明
本文为 Jimmy Song 原创。转载请注明来源: https://jimmysong.io/blog/microservice-auth-methods/
查看本文大纲

在现代微服务架构中,安全性是一个至关重要的方面。随着微服务数量的增加,如何确保服务间的安全通信成为了一个挑战。本文将介绍几种常见的微服务认证方式,帮助你在设计和实现微服务系统时选择合适的认证方案。

微服务中常用的认证方式

下表列出了几种微服务中常用的认证方式,并从优点、缺点、适用场景和现实示例等维度进行比较。

认证方式 优点 缺点 运行位置 适用场景 典型用途 现实使用场景
JWT 自包含令牌,减少服务器负担 令牌较大,可能会增加带宽开销 API 网关、服务间 微服务之间无状态通信 用户认证和授权 在微服务架构中,用户认证(如 Auth0、Firebase)
OAuth 2.0 广泛支持,灵活性高 实现复杂,需要额外的交互 API 网关 第三方应用授权 第三方应用访问用户数据 Github OAuth,用于第三方应用访问 Github 数据和 API
mTLS 高安全性,防止中间人攻击 证书管理复杂,性能开销较大 服务间 高安全性要求的通信 安全敏感的服务通信 银行系统中的服务通信
Basic 认证 简单易实现 不安全,容易被拦截 API 网关、服务间 简单的 API 保护 简单的内部服务 Kubernetes API Server 的基本认证
API Key 认证 简单易用 安全性低,容易被滥用 API 网关、服务间 低安全性要求的场景 简单的服务访问控制 各种公共 API,如 OpenAI API

下面我们将详细介绍这几种常见的认证方式。

JWT 认证

JWT(JSON Web Token)最早由 IETF JSON Web Token (JWT) 工作组提出,并在 2015 年作为 RFC 7519 标准正式发布。JWT 的设计目标是提供一种紧凑且自包含的方式,用于在各方之间安全地传递信息。由于其易于使用和无状态的特性,JWT 迅速被广泛采用,成为身份验证和信息交换的标准之一,特别是在微服务和现代 Web 应用中。

下图展示的是 JWT 认证流程。

image
JWT 认证流程

JWT 认证流程说明:

  1. 用户提供凭证
  2. 客户端请求访问令牌
  3. 认证服务器返回 JWT 令牌
  4. 客户端带 JWT 令牌请求资源服务器
  5. 资源服务器验证 JWT

JWT 的格式说明及示例

JWT(JSON Web Token)由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature),分别通过 Base64 编码后用点(.)连接在一起组成。

  1. 头部(Header):头部包含令牌类型和签名算法。

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  2. 载荷(Payload):载荷包含声明(claims),即关于用户或其他数据的断言。

    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022
    }
    
  3. 签名(Signature):签名由编码后的头部、编码后的载荷以及一个密钥通过头部中指定的算法生成。

    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      secret
    )
    

下面是一个 JWT 令牌示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

OAuth 2.0

OAuth(Open Authorization)协议最早由 Blaine Cook 和 Chris Messina 在 2006 年提出。最初的目标是为 Twitter 提供一个开放的授权标准。OAuth 1.0 于 2007 年发布,提供了一个允许用户授权第三方应用访问其资源的标准化方式,但由于其复杂的签名机制和其他安全问题,受到了一些限制。

为了克服这些缺点,IETF(Internet Engineering Task Force)成立了 OAuth 工作组,旨在开发一个更简化、更灵活的授权协议。2012 年,OAuth 2.0 正式发布(RFC 6749 和 RFC 6750)。OAuth 2.0 简化了授权流程,增加了多种授权模式,如授权码模式、简化模式、资源所有者密码凭证模式和客户端凭证模式。

OAuth 2.0 迅速成为行业标准,广泛应用于各种网络服务和应用程序,如 Google、Facebook、GitHub 等。在此基础上,出现了多个扩展和补充协议(如 OpenID Connect),进一步增强了 OAuth 2.0 的功能和安全性。

OAuth 2.0 的发展和扩展使其成为现代互联网身份验证和授权的重要基石,提供了灵活和安全的解决方案,满足了不断变化的网络应用需求。

下图展示的是 OAuth 2.0 认证流程。

image
OAuth 2.0 认证流程

OAuth 2.0 认证流程说明:

  1. 用户请求访问资源
  2. 客户端请求认证
  3. 用户登录并授权
  4. 认证服务器返回授权码
  5. 客户端交换授权码获取访问令牌
  6. 客户端带访问令牌请求资源服务器

OAuth 2.0 授权码

在 OAuth 2.0 授权码模式中,授权码是客户端在用户授权后从授权服务器获取的短期凭证,用于交换访问令牌。授权码是一个临时的字符串,可以在授权服务器和客户端之间传递以获得更安全的访问令牌。

OAuth 2.0 扩展

OAuth 2.0 在发展过程中,为了适应不同的场景,发展出了众多的扩展,下表罗列出一些常用的扩展名称、主要功能及适用场景。

扩展名称 主要功能 适用场景
授权码 PKCE 扩展 提高授权码模式的安全性,防止授权码拦截攻击 公共客户端(如移动应用、单页应用)
动态客户端注册协议 允许客户端动态注册和更新客户端信息 自动化和灵活性要求高的系统
Token Introspection 允许资源服务器验证和获取访问令牌的详细信息 需要验证令牌有效性和获取令牌详细信息的场景
Token Revocation 提供令牌撤销的标准接口 提高系统安全性和控制能力
Device Authorization Grant 允许输入受限的设备通过其他设备完成身份验证 智能电视、游戏机等输入能力有限的设备
Mutual TLS Client Authentication 基于双向 TLS 的客户端认证 高安全性要求的应用场景
Resource Indicators 允许客户端在授权请求中指定访问的资源服务器 多资源服务器的支持
Step-up Authentication Challenge Protocol 允许资源服务器按需请求更强的身份验证(如多因素认证) 高风险操作的高级认证

OAuth 2.0 授权流程(以 Github 为例)

GitHub 使用 OAuth 2.0 来授权第三方应用访问用户的 GitHub 数据。OAuth 2.0 令牌在 GitHub 上被称为 “access tokens”,用于验证和授权访问 GitHub API。它提供了一种安全、标准化的方法,允许第三方应用在用户授权的情况下访问 GitHub 资源。通过使用访问令牌,应用程序可以代表用户执行各种操作,如读取用户信息、访问仓库、创建 gists 等。这个过程确保了用户的安全和隐私,同时简化了应用程序的认证和授权流程。

以下是使用 GitHub OAuth 2.0 令牌的详细流程和示例:

  1. 用户授权:用户在第三方应用程序的界面上点击“Login with GitHub”按钮。应用程序将用户重定向到 GitHub 的授权页面。

  2. 获取授权码:用户在 GitHub 授权页面上登录并同意授权,GitHub 会将用户重定向回应用程序,并在 URL 参数中附带一个授权码(authorization code)。

    示例:

    https://yourapp.com/callback?code=AUTHORIZATION_CODE
    
  3. 交换访问令牌:应用程序服务器使用授权码向 GitHub 的授权服务器请求访问令牌。

    请求示例:

    POST https://github.com/login/oauth/access_token
    Content-Type: application/json
    Accept: application/json
    
    {
      "client_id": "YOUR_CLIENT_ID",
      "client_secret": "YOUR_CLIENT_SECRET",
      "code": "AUTHORIZATION_CODE",
      "redirect_uri": "https://yourapp.com/callback"
    }
    
  4. GitHub 返回访问令牌:GitHub 验证请求并返回访问令牌。

    响应示例:

    {
      "access_token": "YOUR_ACCESS_TOKEN",
      "token_type": "bearer",
      "scope": "repo,gist"
    }
    
  5. 使用访问令牌访问资源:应用程序使用获取的访问令牌访问 GitHub API。

    请求示例:

    curl -H "Authorization: token YOUR_ACCESS_TOKEN" https://api.github.com/user
    

    响应示例:

    {
      "login": "github-user",
      "id": 1,
      "node_id": "MDQ6VXNlcjE=",
      "avatar_url": "https://github.com/images/avatar.jpg",
      "name": "Github User",
      "company": "GitHub",
      "blog": "https://example.com",
      "location": "Earth",
      "email": "[email protected]"
    }
    

访问令牌的特点和使用

  1. 权限范围(Scopes):访问令牌的权限范围由用户在授权时指定,可以包括读取用户资料、访问用户仓库、管理 gists 等。例如,在上述示例中,scope 包含 repogist

  2. 有效期和刷新:访问令牌的有效期可以是长期的也可以设置时间范围,直到用户主动撤销。

  3. 安全传输:访问令牌应通过 HTTPS 传输,以确保其不被截获。

mTLS

mTLS(Mutual TLS)是一种在客户端和服务器之间进行双向身份验证的技术,最早起源于 TLS(传输层安全协议),TLS 的前身 SSL(安全套接层)协议于 1995 年由 Netscape 开发。随着互联网安全需求的增加,TLS 逐步发展为一个高度安全的通信标准,而 mTLS 则在此基础上进一步提升了安全性,通过要求双方互相验证身份,广泛应用于金融、医疗等对安全性要求极高的领域。

下图展示的是 mTLS 认证流程。

image
mTLS 认证流程

mTLS 认证流程说明:

  1. 客户端与服务器互相发送证书
  2. 双方验证对方证书
  3. 建立安全连接

更多关于 TLS 和 mTLS 的内容请参考博客 如何理解 Istio 中的 mTLS 流量加密

Basic 认证

Basic 认证是一种最早由 HTTP/1.0 规范(RFC 1945)定义的简单认证机制,它通过将用户名和密码进行 Base64 编码后附加到 HTTP 请求头中进行身份验证。由于实现简单且易于使用,Basic 认证在早期的 Web 应用中被广泛采用。然而,由于其固有的安全性问题(如明文传输容易被截获),它在现代应用中通常与 HTTPS 一起使用,或被更安全的认证方式所替代。

下图展示的是 Basic 认证流程。

image
Basic 认证流程

Basic 认证流程说明:

  1. 用户提供用户名和密码
  2. 客户端带用户名和密码请求资源服务器
  3. 资源服务器验证

Basic 示例

Basic 认证使用 Base64 编码的用户名和密码进行认证。下面是使用 curl 命令进行 Basic 认证请求的示例:

curl -u <username>:<password> https://api.example.com/data

如果用户名为 admin,密码为 password123,请求示例如下:

curl -u admin:password123 https://api.example.com/data

API Key 认证

API Key 认证是一种通过在请求中包含预先分配的唯一密钥来进行身份验证的方法,最早在 2000 年代初随着 Web API 的兴起而流行。API Key 认证由于其简单易用和便于管理的特性,被广泛应用于各种公共和私有 API 中。尽管它的安全性较低,容易被滥用,但在许多场景中仍然是控制访问的一种有效手段,特别是对于不需要高度安全保护的应用。

下图展示的是 API Key 认证流程。

image
API Key 认证流程

API Key 认证流程说明:

  1. 客户端带 API Key 请求资源服务器
  2. 资源服务器验证 API Key

API Key 示例

API Key 是在请求中传递的一个唯一标识符,用于验证客户端身份。API Key 通常通过 HTTP 请求头或 URL 参数传递。

HTTP 请求头中的 API Key 示例:

curl -H "Authorization: ApiKey YOUR_API_KEY" https://api.example.com/data

URL 参数中的 API Key 示例:

curl https://api.example.com/data?api_key=YOUR_API_KEY

API Key 格式通常是一个字符串,包含字母和数字,例如:

1234567890abcdef1234567890abcdef

总结

在微服务架构中选择合适的认证方式至关重要。不同的认证方式在安全性、复杂性和适用场景上各有优劣。本文介绍了 JWT、OAuth 2.0、mTLS、Basic 认证和 API Key 认证五种常见的认证方式,并提供了它们的优缺点和适用场景。此外,其他常见的认证方式如 SAML、LDAP、Kerberos 和 OpenID Connect 也广泛应用于不同的互联网应用场景,特别是在单点登录和跨域认证方面。希望这些信息能帮助你在设计和实现微服务系统时选择最合适的认证方案。

最后更新于 2024/12/12