跳转至

API Key 管理指南

文档版本: 1.9.0 最后更新: 2026-09-15 Git 提交: fb0cd62f 作者: Lincoln

概述

JAiRouter 的 API Key 认证功能为系统提供了安全的访问控制机制。通过 API Key,您可以控制谁可以访问您的 AI 模型服务,并为不同的用户分配不同的权限级别。

功能特性

核心功能

  • 多级权限控制:支持 admin、read、write、delete 等不同权限级别
  • 过期时间管理:支持设置 API Key 的过期时间
  • 使用统计:记录每个 API Key 的使用情况
  • 缓存优化:支持 Redis 和本地缓存,提升认证性能
  • 动态管理:支持运行时添加、删除和更新 API Key
  • 持久化存储:支持将 API Key 信息存储在 H2 数据库中
  • H2 数据库默认存储:H2 数据库现在是 API Key 数据的默认持久化存储方式,提供更好的性能和可靠性

安全增强功能 (v1.6.1+)

  • SHA-256 哈希存储:API Key 使用 SHA-256 + 盐值哈希存储,替代明文存储
  • 管理接口速率限制:管理接口添加速率限制 (30/min, 100/hour, 10 create/hour)
  • IP 白名单:支持 IP 白名单功能,限制 API Key 只能从特定 IP 使用
  • 每日请求限制:支持设置每日请求次数上限

高级管理功能 (v1.6.2+)

  • 批量导入/导出:支持批量导入导出 API Key,便于迁移和备份
  • 密钥自动轮换:支持配置密钥自动轮换周期,增强安全性
  • 过期密钥自动清理:自动禁用过期的 API Key
  • 创建者信息记录:记录 API Key 创建者和创建时的 IP 地址

快速开始

1. 启用 API Key 认证

在 application.yml 中启用安全功能:

jairouter:
  security:
    enabled: true
    api-key:
      enabled: true
      header-name: "X-API-Key"

2. 配置 API Key

jairouter:
  security:
    api-key:
      keys:
        - key-id: "admin-key-001"
          key-value: "${ADMIN_API_KEY}"
          description: "管理员API密钥"
          permissions: ["admin", "read", "write", "delete"]
          expires-at: "2027-12-31T23:59:59"
          enabled: true

3. 客户端使用

在 HTTP 请求头中添加 API Key:

curl -H "X-API-Key: your-api-key-here" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"model": "gpt-3.5-turbo", "messages": [...]}' \
     http://localhost:8080/v1/chat/completions

详细配置

API Key 配置参数

参数类型默认值说明
enabledbooleantrue是否启用 API Key 认证
header-namestring"X-API-Key"API Key 请求头名称
default-expiration-daysint365默认过期天数
cache-enabledbooleantrue是否启用缓存
cache-expiration-secondsint3600缓存过期时间(秒)

API Key 属性

每个 API Key 包含以下属性:

- key-id: "unique-key-identifier"      # 唯一标识符
  key-value: "actual-api-key-string"   # 实际的 API Key 值
  description: "Key description"        # 描述信息
  permissions: ["read", "write"]        # 权限列表
  expires-at: "2027-12-31T23:59:59"    # 过期时间
  enabled: true                         # 是否启用
  daily-token-limit: 100000            # 每日 Token 使用限额(可选)
  rate-limit-per-minute: 100           # 每分钟请求速率限制(可选)
  quota-alert-threshold: 80           # 告警阈值百分比(可选)
  metadata:                            # 元数据
    created-by: "admin"
    department: "IT"

配额管理配置 (v2.7.6+)

JAiRouter 支持全面的 API Key 配额管理功能,包括每日 Token 使用限额、请求速率限制和告警阈值。

配置参数

参数类型默认值说明
daily-token-limitlong0(无限制)每日 Token 使用上限
daily-request-limitlong0(无限制)每日请求数上限
rate-limit-per-minuteint0(无限制)每分钟请求次数上限
quota-alert-thresholddouble0.8告警阈值(0.0–1.0,如 0.8 = 80%)

配置示例

jairouter:
  security:
    api-key:
      keys:
        - key-id: "limited-api-key"
          key-value: "${LIMITED_API_KEY}"
          description: "带配额限制的 API Key"
          permissions: ["read"]
          expires-at: "2027-12-31T23:59:59"
          enabled: true
          daily-token-limit: 100000      # 每日 10 万 Token
          rate-limit-per-minute: 60      # 每分钟 60 次请求
          quota-alert-threshold: 0.8     # 使用量达到 80% 时告警(0.0–1.0)

配额管理工作原理

  1. 每日 Token 限额:跟踪每日 Token 使用量。当达到限额时,API 请求将被拒绝,返回 429(Too Many Requests)状态码。

  2. 请求速率限制:使用滑动窗口算法限制每分钟请求次数。当达到限制时,API 请求将被拒绝,返回 429 状态码。

  3. 告警阈值:当使用量超过阈值百分比(如 80%)时,系统会触发告警。这对于监控和主动管理非常有用。

  4. 自动重置:配额计数器每天午夜(00:00:00)自动重置。

监控配额使用情况

您可以通过以下方式监控 API Key 配额使用情况:

  1. Prometheus 指标:
  2. jairouter_security_api_key_daily_token_usage:当日 Token 使用量
  3. jairouter_security_api_key_daily_request_count:当日请求次数
  4. jairouter_security_api_key_quota_exceeded_total:配额超限总次数

  5. 审计日志:配额相关事件会记录在审计日志中。

  6. 控制台:安全 → API 密钥设置限额与告警/重置;运行观测 → 用量统计 → 配额使用查看账本用量与限额对照。

v3.2.0 配额便捷操作 API

端点说明
PUT /api/auth/api-keys/{keyId}/quota只改配额字段(0=不限制;阈值 0.0–1.0)
POST .../quota/batch-reset批量重置(body {keyIds:[]})
POST .../quota/reset-all全量重置
GET .../quota详情含 remainingRequests / remainingTokens(不限制时 -1)

控制台:API 密钥列表操作列 「配额」 抽屉,支持预设(不限制/开发/标准/严格)。

详见 管理 API。

权限级别说明

权限说明适用场景
read只读权限,可以查询模型和发送推理请求普通用户、客户端应用
write写权限,可以修改配置(不包括安全配置)服务管理员
delete删除权限,可以删除配置和数据高级管理员
admin管理员权限,可以管理所有功能包括安全配置系统管理员

环境变量配置

为了安全起见,建议通过环境变量设置 API Key:

Linux/macOS

# 生产环境 API Key 配置
export PROD_ADMIN_API_KEY="your-production-admin-api-key-here"
export PROD_SERVICE_API_KEY="your-production-service-api-key-here"
export PROD_READONLY_API_KEY="your-production-readonly-api-key-here"

# API Key 过期时间配置
export PROD_ADMIN_KEY_EXPIRES="2027-12-31T23:59:59"
export PROD_SERVICE_KEY_EXPIRES="2027-12-31T23:59:59"
export PROD_READONLY_KEY_EXPIRES="2027-12-31T23:59:59"

Windows

# 生产环境 API Key 配置
set PROD_ADMIN_API_KEY=your-production-admin-api-key-here
set PROD_SERVICE_API_KEY=your-production-service-api-key-here
set PROD_READONLY_API_KEY=your-production-readonly-api-key-here

# API Key 过期时间配置
set PROD_ADMIN_KEY_EXPIRES=2027-12-31T23:59:59
set PROD_SERVICE_KEY_EXPIRES=2027-12-31T23:59:59
set PROD_READONLY_KEY_EXPIRES=2027-12-31T23:59:59

Docker

# 生产环境 Docker 部署
docker run -d \
  --name jairouter-prod \
  -p 8080:8080 \
  -e SPRING_PROFILES_ACTIVE=prod \
  -e PROD_ADMIN_API_KEY="your-production-admin-api-key-here" \
  -e PROD_SERVICE_API_KEY="your-production-service-api-key-here" \
  -e PROD_READONLY_API_KEY="your-production-readonly-api-key-here" \
  -e JWT_SECRET="your-production-jwt-secret-here" \
  -e INITIAL_ADMIN_PASSWORD="<强密码>" \
  -e REDIS_HOST="your-redis-host" \
  -e REDIS_PORT="your-redis-port" \
  -e REDIS_PASSWORD="your-redis-password" \
  -v $(pwd)/config:/app/config:ro \
  -v $(pwd)/logs:/app/logs \
  sodlinken/jairouter:latest

缓存配置

Redis 缓存

jairouter:
  security:

本地缓存

jairouter:
  security:

API Key 持久化存储

启用 API Key 持久化

JAiRouter 支持将 API Key 持久化存储以增强管理和监控:

jairouter:
  security:
    api-key:
      # API Key 持久化配置
      persistence:
        enabled: true
        primary-storage: h2    # h2, redis, memory
        fallback-storage: memory  # memory

        # 清理配置
        cleanup:
          enabled: true
          schedule: "0 0 3 * * ?"  # 每天凌晨3点
          retention-days: 365
          batch-size: 1000

        # 内存存储配置
        memory:
          max-keys: 10000
          cleanup-threshold: 0.8  # 80%触发清理
          lru-enabled: true

        # H2 数据库存储配置
        h2:
          table-name: "api_keys"  # 表名
          max-batch-size: 1000    # 批量操作最大大小

API Key 管理功能

启用持久化后,您可以:

  1. 跟踪 API Key:监控所有 API Key 及其状态
  2. 生命周期管理:自动状态更新和清理
  3. 增强安全性:支持 H2 数据库的持久化存储
  4. 审计跟踪:完整的 API Key 操作审计日志
  5. 性能监控:API Key 操作的指标和健康检查

H2 数据库存储优势

使用 H2 数据库存储 API Key 具有以下优势:

  1. 默认存储方式:H2 数据库现在是 API Key 的默认存储方式
  2. 持久化:数据不会因应用重启而丢失
  3. 高性能:嵌入式数据库,无网络开销
  4. 易于维护:单一数据库文件,便于备份
  5. 强大查询:支持复杂的 SQL 查询
  6. 事务支持:保证数据一致性
  7. 可视化管理:H2 控制台便于调试
  8. 生产就绪:满足生产环境要求

H2 数据库表结构

API Key 在 H2 数据库中存储在以下表中:

api_keys 表

字段类型说明
idBIGINT主键
key_idVARCHAR(255)Key ID
key_value_hashVARCHAR(500)Key 值哈希(不存储明文)
descriptionVARCHAR(1000)描述
permissionsTEXT权限列表(JSON)
expires_atTIMESTAMP过期时间
enabledBOOLEAN是否启用
daily_token_limitBIGINT每日 Token 使用限额
rate_limit_per_minuteINT每分钟请求次数限制
quota_alert_thresholdINT告警阈值百分比
today_token_usageBIGINT当日 Token 使用量
today_request_countINT当日请求次数
last_reset_timeTIMESTAMP最后重置时间
created_atTIMESTAMP创建时间
updated_atTIMESTAMP更新时间
metadataTEXT元数据(JSON)
usage_statisticsTEXT使用统计(JSON)

索引优化

系统自动创建以下索引以提高查询性能:

  • idx_apikey_key_id: Key ID索引
  • idx_apikey_enabled: 启用状态索引
  • idx_apikey_expires_at: 过期时间索引
  • idx_apikey_created_at: 创建时间索引

API Key 存储结构

API Key 存储包含以下元数据:

{
  "id": "key-uuid-123",
  "keyId": "admin-key-001",
  "keyValueHash": "sha256-hash-of-key",
  "description": "管理员API密钥",
  "permissions": ["admin", "read", "write", "delete"],
  "expiresAt": "2027-12-31T23:59:59",
  "enabled": true,
  "dailyTokenLimit": 100000,
  "rateLimitPerMinute": 100,
  "quotaAlertThreshold": 0.8,
  "todayTokenUsage": 15000,
  "todayRequestCount": 200,
  "lastResetTime": "2025-01-15T00:00:00Z",
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z",
  "metadata": {
    "createdBy": "admin",
    "department": "IT"
  },
  "usageStatistics": {
    "totalRequests": 1000,
    "successfulRequests": 950,
    "failedRequests": 50,
    "lastUsedAt": "2025-01-15T10:30:00Z"
  }
}

监控和审计

使用统计

系统会自动记录每个 API Key 的使用统计:

  • 总请求数
  • 成功请求数
  • 失败请求数
  • 最后使用时间
  • 每日使用量

审计日志

启用审计功能后,系统会记录所有认证相关的事件:

jairouter:
  security:
    audit:
      enabled: true

监控指标

系统提供以下 Prometheus 指标:

  • jairouter_security_authentication_attempts_total:认证尝试总数
  • jairouter_security_authentication_successes_total:认证成功总数
  • jairouter_security_authentication_failures_total:认证失败总数
  • jairouter_security_authentication_duration_seconds:认证耗时
  • jairouter_security_api_keys_created_total:创建的 API Key 总数
  • jairouter_security_api_keys_used_total:API Key 使用总数
  • jairouter_security_api_keys_revoked_total:撤销的 API Key 总数

安全审计和监控

增强的审计配置

jairouter:
  security:
    # 增强的审计配置
    audit:
      enabled: true
      log-level: "INFO"
      include-request-body: false
      include-response-body: false
      retention-days: 90

审计事件类型

下表是写入审计表的全部 event_type 取值(AuditEventType)。#301 之后未知类型名会被拒绝、 不再静默回退,因此筛选、导出与统计报表请逐字使用这些名字。

API Key 事件

API_KEY_CREATED · API_KEY_USED · API_KEY_UPDATED · API_KEY_REVOKED · API_KEY_EXPIRED · API_KEY_ROTATED · API_KEY_BATCH_IMPORT

API Key 校验失败细分

API_KEY_MISSING · API_KEY_INVALID · API_KEY_VALIDATION_FAILED

JWT 令牌事件

JWT_TOKEN_ISSUED · JWT_TOKEN_REFRESHED · JWT_TOKEN_VALIDATED · JWT_TOKEN_REVOKED · JWT_TOKEN_EXPIRED

安全事件

SECURITY_ALERT · SUSPICIOUS_ACTIVITY · AUTHENTICATION_FAILED · AUTHORIZATION_FAILED · BRUTE_FORCE_ATTEMPT · DATA_SANITIZATION · RESPONSE_SANITIZATION · FULL_CONTENT_ACCESS

调用历史配置

RECORD_LEVEL_CHANGE

系统事件

SYSTEM_CLEANUP · SYSTEM_MAINTENANCE

审计事件结构

{
  "id": "audit-event-uuid",
  "type": "API_KEY_USED",
  "userId": "user123",
  "resourceId": "key-uuid-123",
  "action": "USE_KEY",
  "details": "使用 API Key 访问服务",
  "ipAddress": "192.168.1.100",
  "userAgent": "Mozilla/5.0...",
  "success": true,
  "timestamp": "2025-01-15T10:30:00Z",
  "metadata": {
    "keyId": "admin-key-001",
    "endpoint": "/v1/chat/completions",
    "method": "POST"
  }
}

安全报告生成

生成综合安全报告:

# 获取最近30天的安全报告
curl -X GET "http://localhost:8080/api/security/audit/report?from=2025-01-01&to=2025-01-31" \
     -H "Authorization: Bearer admin_token"

响应包括: - API Key 和 JWT 操作总数 - 失败认证统计 - 可疑活动警报 - 顶级 IP 地址和用户 - 安全事件趋势

最佳实践

1. API Key 安全

  • 使用强密钥:API Key 应该足够长且随机,建议至少 32 个字符
  • 定期轮换:定期更换 API Key,特别是在人员变动时
  • 环境变量:不要在配置文件中硬编码 API Key,使用环境变量
  • 最小权限原则:只授予必要的权限

2. 过期时间管理

  • 合理设置过期时间:根据使用场景设置合适的过期时间
  • 提前续期:在 API Key 过期前及时续期
  • 监控过期:设置告警监控即将过期的 API Key

3. 权限管理

  • 分级授权:根据用户角色分配不同的权限级别
  • 定期审查:定期审查 API Key 的权限分配
  • 及时回收:及时禁用或删除不再使用的 API Key

4. 性能优化

  • 启用缓存:在生产环境中启用 Redis 缓存
  • 合理设置缓存时间:根据安全要求和性能需求设置缓存过期时间
  • 监控缓存命中率:监控缓存性能,及时调整配置

故障排除

常见问题

1. 认证失败

问题:客户端收到 401 Unauthorized 错误

可能原因: - API Key 不正确 - API Key 已过期 - API Key 已被禁用 - 请求头名称不正确

解决方案: 1. 检查 API Key 是否正确 2. 检查 API Key 是否过期 3. 检查配置中的 header-name 设置 4. 查看审计日志获取详细错误信息

2. 权限不足

问题:客户端收到 403 Forbidden 错误

可能原因: - API Key 权限不足 - 访问了需要更高权限的接口

解决方案: 1. 检查 API Key 的权限配置 2. 为 API Key 添加必要的权限 3. 使用具有足够权限的 API Key

3. 性能问题

问题:认证响应时间过长

可能原因: - 缓存未启用或配置不当 - Redis 连接问题 - API Key 数量过多

解决方案: 1. 启用并正确配置缓存 2. 检查 Redis 连接状态 3. 优化 API Key 配置 4. 监控认证性能指标

调试技巧

1. 启用详细日志

logging:
  level:
    org.unreal.modelrouter.auth: DEBUG

2. 检查审计日志

tail -f logs/security-audit.log | grep authentication

3. 监控指标

访问 Prometheus 指标端点:

http://localhost:8080/actuator/prometheus

4. 健康检查

检查系统健康状态:

http://localhost:8080/actuator/health

高级功能

批量导入/导出 (v1.6.2+)

JAiRouter 支持批量导入导出 API Key,便于迁移、备份和批量管理。

导出 API Key

# 导出所有 API Key
curl -X GET "http://localhost:8080/api/auth/api-keys/export" \
     -H "Authorization: Bearer admin_token"

响应格式:

{
  "keys": [
    {
      "keyId": "admin-key-001",
      "description": "管理员密钥",
      "permissions": ["admin", "read", "write", "delete"],
      "expiresAt": "2027-12-31T23:59:59",
      "enabled": true,
      "allowedIpAddresses": ["192.168.1.100"],
      "dailyRequestLimit": 10000,
      "rotationPeriodDays": 90
    }
  ],
  "exportedAt": "2026-04-10T10:30:00Z",
  "totalCount": 10
}

导入 API Key

# 导入 API Key(MERGE 模式 - 保留现有密钥)
curl -X POST "http://localhost:8080/api/auth/api-keys/import" \
     -H "Authorization: Bearer admin_token" \
     -H "Content-Type: application/json" \
     -d '{
       "mode": "MERGE",
       "keys": [
         {
           "keyId": "new-key-001",
           "description": "新导入的密钥",
           "permissions": ["read"],
           "expiresAt": "2026-12-31T23:59:59"
         }
       ]
     }'

# 导入 API Key(REPLACE 模式 - 替换所有现有密钥)
curl -X POST "http://localhost:8080/api/auth/api-keys/import" \
     -H "Authorization: Bearer admin_token" \
     -H "Content-Type: application/json" \
     -d '{
       "mode": "REPLACE",
       "keys": [...]
     }'

导入结果:

{
  "success": true,
  "importedCount": 5,
  "skippedCount": 2,
  "errorCount": 0,
  "details": [
    {"keyId": "new-key-001", "status": "IMPORTED", "message": "成功导入"},
    {"keyId": "existing-key", "status": "SKIPPED", "message": "MERGE模式下跳过已存在的密钥"}
  ]
}

密钥自动轮换 (v1.6.2+)

支持配置密钥自动轮换周期,定期生成新的密钥值,增强安全性。

配置轮换周期

jairouter:
  security:
    api-key:
      keys:
        - key-id: "auto-rotate-key"
          key-value: "${INITIAL_KEY_VALUE}"
          rotation-period-days: 90  # 每90天自动轮换

轮换机制说明

  • 自动执行:ApiKeyRotationScheduler 每小时检查需要轮换的密钥
  • 轮换触发:距离上次轮换超过 rotationPeriodDays 天的密钥会被自动轮换
  • 密钥生成:自动生成新的强随机密钥值
  • 历史记录:保留轮换历史记录,便于审计

手动触发轮换

# 手动重置密钥值
curl -X POST "http://localhost:8080/api/auth/api-keys/{keyId}/reset" \
     -H "Authorization: Bearer admin_token"

IP 白名单 (v1.6.1+)

限制 API Key 只能从特定 IP 地址使用,增强安全性。

配置 IP 白名单

jairouter:
  security:
    api-key:
      keys:
        - key-id: "restricted-key"
          key-value: "${KEY_VALUE}"
          allowed-ip-addresses:
            - "192.168.1.100"      # 单个 IP
            - "10.0.0.0/8"         # CIDR 网段
            - "172.16.0.0-172.16.255.255"  # IP 范围

API 端点配置

# 更新 IP 白名单
curl -X PUT "http://localhost:8080/api/auth/api-keys/{keyId}" \
     -H "Authorization: Bearer admin_token" \
     -H "Content-Type: application/json" \
     -d '{
       "allowedIpAddresses": ["192.168.1.100", "10.0.0.0/8"]
     }'

每日请求限制 (v1.6.1+)

设置每个 API Key 的每日请求次数上限,防止滥用。

配置每日限制

jairouter:
  security:
    api-key:
      keys:
        - key-id: "limited-key"
          key-value: "${KEY_VALUE}"
          daily-request-limit: 10000  # 每天最多 10000 次请求

限制机制说明

  • 计数方式:基于 UTC 日期进行计数,每日 0:00 重置
  • 超限处理:超过限制后返回 429 Too Many Requests
  • 统计查询:可通过管理 API 查询当前使用量

过期密钥自动清理 (v1.6.2+)

ApiKeyExpirationScheduler 自动禁用过期的 API Key。

清理机制

  • 检查频率:每小时检查一次
  • 处理方式:自动将过期密钥设置为 enabled: false
  • 通知机制:可配置告警通知即将过期的密钥

管理接口速率限制 (v1.6.1+)

为防止管理 API 被滥用,添加了速率限制:

操作类型限制
一般管理操作30 次/分钟
每小时总限制100 次/小时
创建密钥10 次/小时

超限后将返回 429 Too Many Requests 错误。

示例配置

开发环境

jairouter:
  security:
    enabled: true
    api-key:
      enabled: true
      default-expiration-days: 30
      keys:
        - key-id: "dev-admin"
          key-value: "dev-admin-key-12345"
          permissions: ["admin", "read", "write", "delete"]
          expires-at: "2027-12-31T23:59:59"

生产环境

jairouter:
  security:
    enabled: true
    api-key:
      enabled: true
      cache-enabled: true
      keys:
        - key-id: "prod-admin"
          key-value: "${PROD_ADMIN_API_KEY}"
          permissions: ["admin", "read", "write", "delete"]
          expires-at: "${PROD_ADMIN_KEY_EXPIRES}"
        - key-id: "prod-service"
          key-value: "${PROD_SERVICE_API_KEY}"
          permissions: ["read", "write"]
          expires-at: "${PROD_SERVICE_KEY_EXPIRES}"

相关文档