a6-plugin-hmac-auth
概览
hmac-auth 插件使用 HMAC(Hash-based Message
Authentication Code)签名对请求进行认证。客户端会基于
请求方法、路径、日期以及可选请求头/请求体计算 HMAC 签名,然后将其放入
Authorization 请求头中。Apache APISIX会在服务端重新计算签名并校验
其是否匹配。这种方式无需在线路上传输密钥,
即可验证请求完整性。
适用场景
- 请求完整性校验(防止 API 调用被篡改)
- 适用于双方共享密钥的服务间认证
- 需要校验请求体完整性的 API
- Token 或密码不应出现在请求中的环境
插件配置参考(路由/服务)
| 字段 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
allowed_algorithms | array | 否 | ["hmac-sha1","hmac-sha256","hmac-sha512"] | 允许使用的 HMAC 算法 |
clock_skew | integer | 否 | 300 | 客户端与服务端之间允许的最大时间差,单位秒 |
signed_headers | array | 否 | — | HMAC 签名中要求包含的额外请求头 |
validate_request_body | boolean | 否 | false | 通过 SHA-256 摘要校验请求体完整性 |
hide_credentials | boolean | 否 | false | 转发到上游前移除 Authorization 请求头 |
anonymous_consumer | string | 否 | — | 未认证请求使用的消费者用户名 |
realm | string | 否 | "hmac" | WWW-Authenticate 响应头中的 Realm |
消费者凭证参考
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
key_id | string | 是 | 消费者的唯一标识符 |
secret_key | string | 是 | 用于 HMAC 计算的 Secret,存储到 etcd 时自动加密 |
分步操作:在路由上启用 hmac-auth
1. 创建消费者
a6 consumer create -f - <<'EOF'
{
"username": "alice"
}
EOF
2. 添加 hmac-auth 凭证
将凭证保存为 credential.yaml,然后创建该凭证:
id: cred-alice-hmac
plugins:
hmac-auth:
key_id: alice-key
secret_key: alice-secret-key-value
a6 credential create --consumer alice -f credential.yaml
3. 创建启用 hmac-auth 的路由
a6 route create -f - <<'EOF'
{
"id": "hmac-protected",
"uri": "/api/*",
"plugins": {
"hmac-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 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()
# Use these headers in request:
# 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 值 |
algorithm | hmac-sha1、hmac-sha256、hmac-sha512 之一 |
headers | 以空格分隔的列表:@request-target date [additional...] |
signature | Base64 编码的 HMAC 签名 |