跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:hmac-auth 插件

概览

hmac-auth 插件使用 HMAC(Hash-based Message Authentication Code)签名对请求进行认证。客户端会基于 请求方法、路径、日期以及可选请求头/请求体计算 HMAC 签名,然后将其放入 Authorization 请求头中。API7 企业版会在服务端重新计算签名并校验 其是否匹配。这种方式无需在线路上传输密钥, 即可验证请求完整性。

适用场景

  • 请求完整性校验(防止 API 调用被篡改)
  • 适用于双方共享密钥的服务间认证
  • 需要校验请求体完整性的 API
  • Token 或密码不应出现在请求中的环境

插件配置参考(路由/服务)

字段类型是否必填默认值说明
allowed_algorithmsarray["hmac-sha1","hmac-sha256","hmac-sha512"]允许使用的 HMAC 算法
clock_skewinteger300客户端与服务端之间允许的最大时间差,单位秒
signed_headersarrayHMAC 签名中要求包含的额外请求头
validate_request_bodybooleanfalse通过 SHA-256 摘要校验请求体完整性
hide_credentialsbooleanfalse转发到上游前移除 Authorization 请求头
anonymous_consumerstring未认证请求使用的消费者用户名
realmstring"hmac"WWW-Authenticate 响应头中的 Realm

消费者凭证参考

字段类型是否必填说明
key_idstring消费者的唯一标识符
secret_keystring用于 HMAC 计算的密钥,会在数据库中自动加密

分步操作:在路由上启用 hmac-auth

1. 创建消费者

a7 consumer create -g default -f - <<'EOF'
{
"username": "alice"
}
EOF

2. 添加 hmac-auth 凭证

curl -k "https://$(a7 context current -o json | jq -r .server):7443/apisix/admin/consumers/alice/credentials" \
-X PUT \
-H "X-API-KEY: $(a7 context current -o json | jq -r .token)" \
-d '{
"id": "cred-alice-hmac",
"plugins": {
"hmac-auth": {
"key_id": "alice-key",
"secret_key": "alice-secret-key-value"
}
}
}'

3. 创建启用 hmac-auth 的路由

a7 route create -g default -f - <<'EOF'
{
"id": "hmac-protected",
"uri": "/api/*",
"plugins": {
"hmac-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF

4. 生成签名并测试

HMAC 签名遵循 HTTP Signatures 草案

Python 示例:

import hmac, hashlib, base64
from datetime import datetime, timezone

key_id = "alice-key"
secret_key = b"alice-secret-key-value"
method = "GET"
path = "/api/users"
algorithm = "hmac-sha256"

gmt_time = datetime.now(timezone.utc).strftime('%a, %d %b %Y %H:%M:%S GMT')

signing_string = f"{key_id}\n{method} {path}\ndate: {gmt_time}\n"

signature = base64.b64encode(
hmac.new(secret_key, signing_string.encode(), hashlib.sha256).digest()
).decode()

# 请求中使用以下请求头:
# Date: {gmt_time}
# Authorization: Signature keyId="{key_id}",algorithm="{algorithm}",
# headers="@request-target date",signature="{signature}"

curl 示例:

curl -i http://127.0.0.1:9080/api/users \
-H "Date: $(date -u +'%a, %d %b %Y %H:%M:%S GMT')" \
-H 'Authorization: Signature keyId="alice-key",algorithm="hmac-sha256",headers="@request-target date",signature="<computed_signature>"'

Authorization 请求头格式

Signature keyId="{key_id}",algorithm="{algorithm}",headers="{signed_headers}",signature="{signature}"
组件说明
keyId消费者的 key_id
algorithmhmac-sha1hmac-sha256hmac-sha512 之一
headers以空格分隔的列表:@request-target date [additional...]
signatureBase64 编码的 HMAC 签名

签名字符串构造

签名字符串以换行分隔:

{key_id}\n
{METHOD} {path}\n
date: {Date header value}\n
{additional-header}: {value}\n
  • 第一行:key_id
  • 第二行:HTTP 方法 + 空格 + 请求路径
  • 后续行:小写请求头名称及其值
  • 每一行都以 \n 结束

常见模式

限制为指定算法

{
"plugins": {
"hmac-auth": {
"allowed_algorithms": ["hmac-sha256", "hmac-sha512"]
}
}
}

增大时钟偏差容忍度

{
"plugins": {
"hmac-auth": {
"clock_skew": 600
}
}
}

允许最多 10 分钟的时间差。

校验请求体

{
"plugins": {
"hmac-auth": {
"validate_request_body": true
}
}
}

客户端必须包含 Digest: SHA-256={base64_sha256_of_body} 请求头。API7 企业版 会重新计算请求体摘要;如果不匹配,则拒绝请求。

要求签名包含自定义请求头

{
"plugins": {
"hmac-auth": {
"signed_headers": ["x-custom-header-a", "x-custom-header-b"]
}
}
}

添加到上游的请求头

请求头
X-Consumer-Username消费者用户名
X-Credential-Identifier凭证 ID
X-Consumer-Custom-Id消费者的 labels.custom_id(如已设置)

故障排查

现象原因修复方式
401 签名不匹配签名字符串与服务端预期不同检查换行格式、请求头小写形式,以及第一行为 key_id
401 时钟偏移Date 请求头与服务端时间差距过大同步时钟或增大 clock_skew
401 算法不允许客户端使用的算法不在 allowed_algorithms将算法加入允许列表,或修改客户端
401 请求体摘要不匹配计算摘要后请求体发生变化根据实际请求体重新计算 Digest 请求头
签名难以调试签名字符串较复杂在客户端记录精确签名字符串并进行比较

配置同步示例

version: "1"
gateway_groups:
- name: default
consumers:
- username: alice
routes:
- id: hmac-protected
uri: /api/*
plugins:
hmac-auth: {}
upstream:
type: roundrobin
nodes:
- host: backend
port: 8080
weight: 1

注意:消费者凭证(key_id/secret_key)必须单独创建 需要通过 Admin API 管理;a7 config sync 会管理消费者资源,但 凭证属于子资源。


本页面由 api7/a7 仓库中的 a7-plugin-hmac-auth/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。