Skip to content

微服务中常用的认证方式

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

认证方式优点缺点运行位置适用场景典型用途现实使用场景
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)是一种提供紧凑且自包含方式的认证机制,广泛应用于微服务和现代 Web 应用中。

流程说明

JWT 认证流程

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

JWT 的格式

JWT 由 头部(Header)载荷(Payload)签名(Signature) 组成,分别通过 Base64 编码后用点(.)连接在一起组成。格式如下:

json
{
  "alg": "HS256",
  "typ": "JWT"
}
json
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
plaintext
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

下面是一个 JWT 令牌示例:

plaintext
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM6MDIyfQ.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 认证流程:

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 资源。

授权过程示例

  1. 用户授权:用户在第三方应用程序的界面上点击“Login with GitHub”按钮。应用程序将用户重定向到 GitHub 的授权页面。
  2. 获取授权码:用户在 GitHub 授权页面上登录并同意授权,GitHub 会将用户重定向回应用程序,并在 URL 参数中附带一个授权码(authorization code)。

示例:

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

请求示例:

http
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://xxxxxx.com/callback"
}
  1. GitHub 返回访问令牌:GitHub 验证请求并返回访问令牌。

响应示例:

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

请求示例:

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

响应示例:

json
{
  "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": "github-user@example.com"
}

访问令牌的特点和使用

  1. 权限范围(Scopes):访问令牌的权限范围由用户在授权时指定,例如读取用户资料、访问用户仓库、管理 gists 等。
  2. 有效期和刷新:访问令牌的有效期可以是长期的,也可以设置为短期直到用户主动撤销。
  3. 安全传输:访问令牌应通过 HTTPS 传输,以确保其不被截获。

mTLS

mTLS(Mutual TLS)是一种双向身份验证技术,适用于高安全性场景。

认证流程

mTLS 认证流程

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

Basic

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

流程说明

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 认证流程

  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

总结

在微服务架构中选择合适的认证方式至关重要。本文比较了 JWTOAuth 2.0mTLSBasic 认证API Key 认证 的优缺点和适用场景。希望能帮助你选择最适合的认证方案!

粤ICP备20009776号