Kong 如何使用 standard-webhooks 插件校验带签名和时间戳的 Webhook
Kong 如何使用 standard-webhooks 插件校验带签名和时间戳的 Webhook【免费下载链接】kong The API and AI Gateway项目地址: https://gitcode.com/GitHub_Trending/ko/kong当你的服务接收外部系统推送的 Webhook 时需要确认请求确实来自可信的发送方并且不是被重放的旧请求。Kong 3.8 起内置的standard-webhooks插件可以完成这件事它要求入站请求携带webhook-id、webhook-timestamp、webhook-signature三个请求头插件用你配置的密钥重新计算 HMAC-SHA256 签名并比对同时校验时间戳是否在容差范围内不满足任一条件的请求都会被拒绝。本文基于仓库中的插件实现与测试用例说明如何配置该插件、如何构造合法的签名请求以及用哪些请求验证各校验分支的行为。插件校验逻辑与签名算法插件在 access 阶段工作只支持 HTTP 协议。校验流程定义在 internal.lua 中按顺序检查请求头完整性webhook-id、webhook-signature、webhook-timestamp三个头缺一不可缺失任一项直接返回400。时间戳容差时间戳会被tonumber解析解析失败按0处理必然触发容差校验失败若ngx.now() - ts超过配置的tolerance_second返回400。请求体必须存在非空 body否则返回400。签名比对用配置的secret_v1计算期望签名并与webhook-signature头逐一比较不一致返回400。签名算法由sign函数定义webhook-signature v1, .. base64( HMAC-SHA256( secret_v1, webhook-id .. . .. webhook-timestamp .. . .. 请求体 ) )即拼接串是webhook-id、webhook-timestamp、原始请求体三者用.连接对整个拼接串做 HMAC-SHA256再做 Base64 编码最后加上v1,前缀。发送方必须使用同一个 secret 按同一算法计算签名。准备条件Kong 3.8 及以上版本该插件由 3.8.0 引入见 3.8.0 变更记录 与 3.8.0.md。一个已定义好的 service 和 route指向接收 Webhook 的上游应用。集成测试中的最小结构就是一条paths {/}的 route加一个挂在 route 上的standard-webhooks插件见 02-integration_spec.lua 的lazy_setup。配置插件插件配置项定义在 schema.lua配置项类型说明config.secret_v1string必填与发送方约定的 Webhook 密钥字段标记为encrypted在数据库中加密存储config.tolerance_secondinteger时间戳容差秒。不设置时默认3005 分钟必须 ≥ 0tolerance_second的 schema 描述原文“Tolerance of the webhook timestamp in seconds. If the webhook timestamp is older than this number of seconds, it will be rejected with a 400 response.”方式一声明式配置与集成测试一致的声明式配置写法如下其中secret_v1替换为你与发送方约定的密钥_format_version: 3.8 services: - name: webhook-receiver url: http://your-upstream:8080/ routes: - name: webhook-route service: webhook-receiver paths: - / plugins: - name: standard-webhooks route: webhook-route config: secret_v1: MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSwMfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw是集成测试中使用的密钥值生产环境请替换为自己的密钥url为你的真实上游地址。方式二Admin API在已加载 service 和 route 的实例上通过 Admin API 创建挂在 route 上的插件curl -i -X POST http://127.0.0.1:8001/plugins \ --data namestandard-webhooks \ --data config.secret_v1MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw \ --data config.tolerance_second300其中8001是 Kong Admin API 的默认监听端口config.tolerance_second可省略省略时使用默认值300。schema 校验规则见 01-unit_spec.luasecret_v1缺省会报required field missing传非字符串报expected a stringtolerance_second传非整数报expected an integer传负数报value must be greater than -1。构造合法的签名请求并验证签名必须与请求体逐字节一致且时间戳要接近当前时间默认容差 300 秒。下面给出与集成测试相同请求的 shell 版本SECRETMfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw MSG_IDmsg_p5jXN8AQM9LWM0D4loKWxJek BODY{foo:bar} TS$(date %s) # 按 internal.lua 的算法计算签名v1,base64(HMAC-SHA256(secret, id.ts.body)) SIGv1,$(printf %s ${MSG_ID}.${TS}.${BODY} | openssl dgst -sha256 -hmac $SECRET -binary | base64) curl -i http://127.0.0.1:8000/ \ -H Content-Type: application/json \ -H webhook-id: ${MSG_ID} \ -H webhook-timestamp: ${TS} \ -H webhook-signature: ${SIG} \ -d ${BODY}签名计算命令就是internal.lua中sign函数的等价实现printf %s保证拼接串不带换行、与 body 原样一致。成功判定请求头与签名全部正确时代理请求透传到上游集成测试断言此时返回200测试用例 “accepts correct signature”。逐分支验证拒绝行为以下四种请求都对应集成测试中的用例预期全部返回400可在你的实例上逐一复现# 1. 缺少 webhook-signature 头 —— 测试断言 400rejects missing headers curl -i http://127.0.0.1:8000/ \ -H Content-Type: application/json \ -H webhook-id: ${MSG_ID} \ -H webhook-timestamp: ${TS} \ -d ${BODY} # 2. 时间戳不可解析如 XYZ解析失败按 0 处理必然超容差 —— 断言 400rejects invalid timestamp curl -i http://127.0.0.1:8000/ \ -H Content-Type: application/json \ -H webhook-id: ${MSG_ID} \ -H webhook-timestamp: XYZ \ -H webhook-signature: asdf \ -d ${BODY} # 3. 三个头齐全但没有请求体 —— 断言 400rejects missing body curl -i http://127.0.0.1:8000/ \ -H Content-Type: application/json \ -H webhook-id: ${MSG_ID} \ -H webhook-timestamp: ${TS} \ -H webhook-signature: asdf # 4. 时间戳为 6 分钟前签名正确但超出默认 300 秒容差—— 断言 400fails because the timestamp tolerance is exceeded OLD_TS$(( $(date %s) - 360 )) OLD_SIGv1,$(printf %s ${MSG_ID}.${OLD_TS}.${BODY} | openssl dgst -sha256 -hmac $SECRET -binary | base64) curl -i http://127.0.0.1:8000/ \ -H Content-Type: application/json \ -H webhook-id: ${MSG_ID} \ -H webhook-timestamp: ${OLD_TS} \ -H webhook-signature: ${OLD_SIG} \ -d ${BODY}需要观察具体失败原因时internal.lua在各拒绝分支会输出 debug 日志missing required headers、timestamp tolerance exceeded、missing required body、signature not matched可在开启 debug 日志级别后对照判断请求卡在哪一步。限制与注意事项插件 schema 中protocols为protocols_http即仅处理 HTTP 路由不适用于 TCP/UDP/GRPC/Stream 路由。该插件只做接收侧校验Kong 负责验证签名与时间戳webhook-signature必须由发送方用同一secret_v1按上述算法计算Kong 本身不负责向第三方推送事件。tolerance_second控制时钟偏差容忍度默认 300 秒对时效要求更高的场景可下调但不能为负。secret_v1在 schema 中标记为encryptedKong 落库时加密保存。签名比对是精确字符串比较signature ~ expected_signature发送方若遗漏v1,前缀或对 body 做了不同的序列化/压缩都会被判为签名不匹配。完成上述四个拒绝用例和一个通过用例后即可以判定standard-webhooks插件在你的路由上按预期工作。插件优先级与版本信息见 handler.lua。【免费下载链接】kong The API and AI Gateway项目地址: https://gitcode.com/GitHub_Trending/ko/kong创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考