apisix~hmac-auth插件的使用
hmac-auth插件需要和 Consumer 一起使用,API 的使用者必须将密匙添加到请求头中以验证其请求,下面介绍它的主要用法
参数
- algorithm 算法 默认hmac-sha256 ["hmac-sha1", "hmac-sha256", "hmac-sha512"],客户端请求头X-HMAC-ALGORITHM=hmac-sha256
- clock_skew 签名允许的时间偏移(以秒为单位)
- access_key Consumer 的 access_key 必须是唯一的,客户端请求时在请求头添加X-HMAC-ACCESS-KEY=access_key值
- signed_headers 要在加密计算中使用的 headers 列表,客户端请求头X-HMAC-SIGNED-HEADERS
- X-HMAC-SIGNATURE 客户端请求头中的签名
消费者配置
- 添加hmac-auth插件,配置access_key,类似于app_id
- 这个消费者有两个能力,除了hmac-auth以外,还有key-auth的能力,即简单的认证方式

签名生成的过程
接下来,我们将以下述请求为例,为你介绍签名生成公式的具体计算过程:
curl -i http://127.0.0.1:9080/index.html?name=james&age=36 \
-H "X-HMAC-SIGNED-HEADERS: User-Agent;x-custom-a" \
-H "x-custom-a: test" \
-H "User-Agent: curl/7.29.0"
- 上文请求默认的 HTTP Method 是 GET,得到 signing_string 为:
"GET"
- 请求的 URI 是 /index.html,根据 HTTP Method + \n + HTTP URI 得到 signing_string 为:
"GET
/index.html"
- URL 中的 query 项是 name=james&age=36,假设 encode_uri_params 为 false,根据 canonical_query_string 的算法,重点是对 key 进行字典排序,得到 age=36&name=james;根据 HTTP Method + \n + HTTP URI + \n + canonical_query_string 得到 signing_string 为:
"GET
/index.html
age=36&name=james"
- access_key 是 user-key,根据 HTTP Method + \n + HTTP URI + \n + canonical_query_string + \n + access_key 得到 signing_string 为:
"GET
/index.html
age=36&name=james
user-key"
- Date 是指
GMT格式的日期,不能缺少,形如 Tue, 19 Jan 2021 11:33:20 GMT, 根据 HTTP Method + \n + HTTP URI + \n + canonical_query_string + \n + access_key + \n + Date 得到 signing_string 为:
"GET
/index.html
age=36&name=james
user-key
Tue, 19 Jan 2021 11:33:20 GMT"
因为人家apisix服务端lua插件源码,使用的是这种GMT格式,所以咱们使用者也需要跟人家保持一致,事实上,我更倾向于使用时间戳,没有日期格式和时区的问题

- signed_headers_string 用来制定参与到签名的 headers,在上面示例中包括 User-Agent: curl/7.29.0 和 x-custom-a: test。
根据 HTTP Method + \n + HTTP URI + \n + canonical_query_string + \n + access_key + \n + Date + \n + signed_headers_string + \n,得到完整的 signing_string 为:
"GET
/index.html
age=36&name=james
user-key
Tue, 19 Jan 2021 11:33:20 GMT
User-Agent:curl/7.29.0
x-custom-a:test
"
Body请求体校验
当 validate_request_body 设置为 true 时,插件将计算请求 body 的 hmac-sha 值,并与请求 headers 中的 X-HMAC-DIGEST 的值进行校验。
X-HMAC-DIGEST: base64(hmac-sha())
X-HMAC-DIGEST: base64(hmac-sha(<body>))
如果没有请求 body,你可以将 X-HMAC-DIGEST 的值设置为空字符串的 HMAC-SHA。
注意:
当开启 body 校验时,为了计算请求 body 的 hmac-sha 值,该插件会把 body 加载到内存中,在请求 body 较大的情况下,可能会造成较高的内存消耗。
为了避免这种情况,你可以通过设置 max_req_body(默认值是 512KB)配置项来配置最大允许的 body 大小,body 超过此大小的请求会被拒绝。
测试插件
假设当前请求为:
curl -i http://127.0.0.1:9080/index.html?name=james&age=36 \
-H "X-HMAC-SIGNED-HEADERS: User-Agent;x-custom-a" \
-H "x-custom-a: test" \
-H "User-Agent: curl/7.29.0"
通过以下 Python 代码为上述请求生成签名 SIGNATURE:
import base64
import hashlib
import hmac
secret = bytes('my-secret-key', 'utf-8')
message = bytes("""GET
/index.html
age=36&name=james
user-key
Tue, 19 Jan 2021 11:33:20 GMT
User-Agent:curl/7.29.0
x-custom-a:test
""", 'utf-8')
hash = hmac.new(secret, message, hashlib.sha256)
# to lowercase base64
print(base64.b64encode(hash.digest()))
| Type | Hash |
|---|---|
| SIGNATURE | 8XV1GB7Tq23OJcoz6wjqTs4ZLxr9DiLoY4PxzScWGYg= |
你也可以参考 Generating HMAC signatures 了解如何使用不同的编程语言生成签名。
签名生成后,你可以通过以下示例使用生成的签名发起请求:
curl -i "http://127.0.0.1:9080/index.html?name=james&age=36" \
-H "X-HMAC-SIGNATURE: 8XV1GB7Tq23OJcoz6wjqTs4ZLxr9DiLoY4PxzScWGYg=" \
-H "X-HMAC-ALGORITHM: hmac-sha256" \
-H "X-HMAC-ACCESS-KEY: user-key" \
-H "Date: Tue, 19 Jan 2021 11:33:20 GMT" \
-H "X-HMAC-SIGNED-HEADERS: User-Agent;x-custom-a" \
-H "x-custom-a: test" \
-H "User-Agent: curl/7.29.0"
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Tue, 19 Jan 2021 11:33:20 GMT
Server: APISIX/2.2
......
你也可以将签名放到请求头 Authorization 字段中:
curl http://127.0.0.1:9080/index.html \
-H 'Authorization: hmac-auth-v1# + ACCESS_KEY + # + base64_encode(SIGNATURE) + # + ALGORITHM + # + DATE + # + SIGNED_HEADERS' -i
postman测试结果
apisix~hmac-auth插件的使用的更多相关文章
- apisix docker镜像构建及插件化开发
高能劝退:lua开发,适合小白看!!! 前段时间有个项目,用的java程序做网关,压测tps只有1k多点,惨不忍睹. 后来公司有个大佬改用apisix做网关,tps飙升到1w多. 于是对神奇的apis ...
- 详解 APISIX Lua 动态调试插件 inspect
作者罗锦华,API7.ai 技术专家/技术工程师,开源项目 pgcat,lua-resty-ffi,lua-resty-inspect 的作者. 原文链接 为什么需要 Lua 动态调试插件? Apac ...
- WebAssembly 助力云原生:APISIX 如何借助 Wasm 插件实现扩展功能?
本文将介绍 Wasm,以及 Apache APISIX 如何实现 Wasm 功能. 作者朱欣欣,API7.ai 技术工程师 原文链接 什么是 Wasm Wasm 是 WebAssembly 的缩写.W ...
- 云原生API网关全生命周期管理Apache APISIX探究实操
@ 目录 概述 定义 NGINX 与 Kong 的痛点 APISIX 的技术优势 特性 架构 应用场景 主要概念 部署 快速入门 quickstart安装 Admin API创建路由 RPM安装 安装 ...
- 为什么 APISIX Ingress 是比 Emissary-ingress 更好的选择?
本文从可扩展性和服务发现集成等多个维度对比了 APISIX Ingress 与 Emissary-ingress 的性能. 作者:容鑫,API7.ai 云原生技术工程师,Apache APISIX C ...
- OpenResty 社区王院生:APISIX 的高性能实践
2019 年 7 月 6 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·上海站,OpenResty 软件基金会联合创始人王院生在活动上做了&l ...
- 当 Amazon Lambda 遇上 Apache APISIX 可以擦出什么火花?
本文首先介绍了什么是 Serverless,以及为什么需要 Serverless:其次,讲述了一个好的网关在 Serverless 架构下的重要性,而 APISIX 就是这样的一个网关:最后,本文重点 ...
- Nginx、OpenResty和Kong的基本概念与使用方法
Nginx.OpenResty和Kong的基本概念与使用方法 2018年10月10日 22:46:08 李佶澳 阅读数 322更多 分类专栏: kubernetes 版权声明:本文为博主原创文章, ...
- 论 Erda 的安全之道
作者|陈建锋 来源|尔达 Erda 公众号 软件研发是一个复杂的工程,不仅需要进行软件的设计.开发.测试.运维,还涉及到大量的人力.物力管理.今天讨论的主角 - "安全",在软 ...
- API 管理在云原生场景下的机遇与挑战
作者 | 张添翼 来源 | 尔达Erda公众号 云原生下的机遇和挑战 标准和生态的意义 自从 Kubernetes v1.0 于 2015 年 7 月 21 日发布,CNCF 组织随后建立以来,其 ...
随机推荐
- VUE3基础环境搭建
VUE3基础环境搭建 1. 安装vue.js npm install vue -g 安装webpack Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bun ...
- DateTimeExtensions:一个轻量C#的开源DateTime扩展方法库
推荐一个专门为System.DateTime编写的扩展方法库. 01 项目简介 该项目主要是为System.DateTime和System.DateTimeOffset的编写的扩展方法,包括自然日期差 ...
- Java验证邮箱是否有用的实现与解析
在现代互联网应用中,邮箱验证是一个常见的需求.通过邮箱验证,开发者可以确保用户提供的邮箱地址是有效的,从而在后续的操作中,如密码重置.通知发送等,依赖这些有效的邮箱地址.本文将详细介绍如何使用Java ...
- CDS标准视图:分配到任务清单的维护包数据 I_PckgTaskListOpalLocData
视图名称:分配到任务清单的维护包数据 I_PckgTaskListOpalLocData 视图类型:基础 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'IPCKTLO ...
- w3cschool-memcached教程
https://www.w3cschool.cn/memcached/ Memcached 教程 Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. 手册简介 Memcached ...
- 【java提高】---细则(4)
java提高(16)---java注解 注解含义注解是JDK1.5之后才有的新特性,它相当于一种标记,在程序中加入注解就等于为程序打上某种标记,之后又通过类的反射机制来解析注解. 一.JDK自带注解 ...
- 类的内部成员之五:内部类(Person.Bird bird = p.new Bird();)
/* * 类的内部成员之五:内部类 * 1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类 * * 2.内部类的分类:成员内部类(静态.非静态) vs 局部内部类(方法 ...
- linux实现人脸识别锁定解锁
环境 archlinux 桌面管理器i3wm 登录管理器 slim python 3.10.4 dlib pip install --user -i https://pypi.tuna.tsinghu ...
- ef 值转换与值比较器
前言 简单介绍一下,值转换器和值比较器. 正文 为什么有值转换器这东西呢? 那就是这个东西一直必须存在. 比如说,我们的c# enum 对应数据库的什么呢? 是int还是string呢? 一般情况下, ...
- dart箭头函数和自执行函数的详解
01==>箭头函数 // List list = ['苹果', '香蕉', '栗子']; // list.forEach((element) { // print(element); // }) ...