3. 安全方案定义:securitySchemes 详解

在 OpenAPI 契约中,securitySchemes 是定义后端鉴权方式的“注册中心”。它位于 components 对象下,声明所有可用的安全方案类型,再由全局或路径级的 security 字段引用。本章逐一拆解五种主流方案:API Key、HTTP Basic、Bearer Token、OAuth2 和 OpenID Connect。

3.1 securitySchemes 结构总览

一个典型的 securitySchemes 定义如下:

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    BasicAuth:
      type: http
      scheme: basic
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    OAuth2Auth:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          scopes:
            read: 读取资源
            write: 写入资源
    OpenIDConnectAuth:
      type: openIdConnect
      openIdConnectUrl: https://auth.example.com/.well-known/openid-configuration
关键原则:每个安全方案必须有一个唯一的键名(如 ApiKeyAuth),后续在 security 字段中通过该键名引用。类型决定了必须提供的其他属性。

3.2 五种安全方案对比

方案类型 type 值 核心属性 典型场景
API Key apiKey in(header/query/cookie)、name 服务间简单鉴权、第三方 API 调用
HTTP Basic http + scheme: basic scheme 遗留系统、快速原型
Bearer Token http + scheme: bearer bearerFormat(可选) JWT 鉴权、OAuth2 访问令牌
OAuth2 oauth2 flows(授权码/隐式/密码/客户端凭证) 用户授权、第三方登录
OpenID Connect openIdConnect openIdConnectUrl 身份认证 + 用户信息获取

3.3 API Key 方案详解

API Key 是最简单的鉴权方式,通过一个预共享的密钥字符串识别调用方。OpenAPI 中需指定密钥的传输位置和名称。

components:
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
    ApiKeyCookie:
      type: apiKey
      in: cookie
      name: session_id
  • in: header — 密钥放在 HTTP 请求头中,如 X-API-Key: abc123。
  • in: query — 密钥作为 URL 查询参数,如 ?api_key=abc123(不推荐,易泄露)。
  • in: cookie — 密钥放在 Cookie 中,适用于浏览器端会话。
安全提示:API Key 本身不提供身份验证(仅识别调用方),且容易在日志或 URL 中泄露。生产环境建议配合 HTTPS 使用,并定期轮换密钥。

3.4 HTTP Basic 与 Bearer Token

两者都属于 type: http,通过 scheme 字段区分。

HTTP Basic

客户端将 用户名:密码 进行 Base64 编码后放入 Authorization 头:

Authorization: Basic base64(username:password)

OpenAPI 定义:

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic

Bearer Token

客户端将令牌直接放入 Authorization 头,格式为 Bearer <token>:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

OpenAPI 定义:

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT   # 可选,说明令牌格式
对比:Basic 每次请求都携带明文密码(仅 Base64 编码,非加密),安全性低;Bearer Token 通常配合 JWT 使用,可携带声明和过期时间,更安全灵活。

3.5 OAuth2 流程详解

OAuth2 是授权框架,OpenAPI 支持四种授权流程(flows)。每个流程需定义授权端点、令牌端点及作用域。

流程类型 flow 键 必需端点 适用场景
授权码模式 authorizationCode authorizationUrl + tokenUrl 服务端 Web 应用、有后端的移动应用
隐式模式 implicit authorizationUrl 纯前端 SPA(已不推荐)
密码模式 password tokenUrl 受信任的第一方应用
客户端凭证模式 clientCredentials tokenUrl 服务间通信、无用户场景

示例:授权码模式定义

components:
  securitySchemes:
    OAuth2Auth:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/oauth/authorize
          tokenUrl: https://auth.example.com/oauth/token
          scopes:
            read: 读取用户资料
            write: 修改用户资料
            admin: 管理权限
作用域(scopes)是 OAuth2 的核心概念,用于限制令牌的权限范围。在 OpenAPI 中,security 字段可指定所需作用域,如 security: [OAuth2Auth: [read, write]]。

3.6 OpenID Connect 方案

OpenID Connect(OIDC)在 OAuth2 之上增加身份认证层。OpenAPI 中只需提供 OIDC 发现 URL,客户端可自动获取授权端点、令牌端点、公钥等信息。

components:
  securitySchemes:
    OIDCAuth:
      type: openIdConnect
      openIdConnectUrl: https://auth.example.com/.well-known/openid-configuration

OIDC 返回的 ID Token(通常为 JWT)包含用户身份声明(sub、name、email 等),后端可据此完成用户认证。

与 OAuth2 的区别:OAuth2 关注授权(“你能访问什么”),OIDC 关注认证(“你是谁”)。OIDC 是 OAuth2 的超集,常用于单点登录(SSO)。

3.7 安全方案选择决策流程

下图展示了根据场景选择安全方案的决策路径:

安全方案选择决策流程 需要哪种安全方案? 需要用户 身份认证? OpenID Connect 需要授权 (作用域)? OAuth2 服务间通信 或简单鉴权? API Key Bearer / Basic 说明:Bearer Token 适合 JWT 场景;Basic 仅用于遗留系统。OAuth2 和 OIDC 需配合 HTTPS 使用。

3.8 安全方案在契约中的引用

定义好 securitySchemes 后,通过全局或路径级的 security 字段引用:

# 全局安全(所有接口默认)
security:
  - BearerAuth: []

# 路径级覆盖(仅 /admin 需要 OAuth2 作用域)
paths:
  /admin/users:
    get:
      security:
        - OAuth2Auth: [admin]
      responses:
        '200':
          description: 用户列表
注意:路径级 security 会覆盖全局设置。如果某个接口不需要鉴权,可显式设置为 security: []。

3.9 常见错误与校验规则

错误类型 示例 正确做法
缺少必需属性 type: apiKey 未指定 in 必须指定 in 和 name
OAuth2 流程拼写错误 authorization_code(下划线) 使用驼峰 authorizationCode
作用域未定义 security: [OAuth2Auth: [read]] 但 flows 中未声明 read 在 flows.scopes 中预先定义所有作用域
Bearer 格式不匹配 bearerFormat: JWT 但实际返回 opaque token 保持 bearerFormat 与实际令牌格式一致
契约校验要点:使用 OpenAPI 校验工具(如 Spectral、Redocly CLI)时,应启用安全方案相关规则,确保每个 security 引用都对应已定义的 securitySchemes,且 OAuth2 作用域在 flows 中已声明。