JMeter配置Hawk认证调用GET API报401的解决方法
JMeter配置Hawk认证解决GET请求401未授权方案
Postman内置Hawk签名逻辑,导出JMeter脚本时不会同步动态签名规则,仅会写入导出时刻生成的固定Authorization头,触发时间戳过期、nonce重复、签名因子不匹配问题,最终返回401。JMeter原生无内置Hawk认证支持,需按以下流程手动配置:
前置确认项
- 已持有完整认证参数:Hawk Auth ID、Hawk Auth Key、对应签名算法
- 已确认目标GET接口的域名、端口、请求路径、查询参数规则,和Postman正常调用时的配置完全一致
操作步骤
1. 导入依赖
将Hawk签名对应的核心Java依赖包放入JMeter安装目录的lib/ext文件夹,重启JMeter使依赖生效。
2. 配置基础HTTP请求
在线程组下添加HTTP请求采样器:
- 填入目标接口域名、端口,请求方法选择
GET - 在路径栏填入接口路径,所有查询参数统一在「参数」标签页按键值对配置,不要手动拼接在路径后,避免签名时路径计算错误
- 给该采样器添加HTTP信息头管理器,不要提前写固定的Authorization值
3. 添加动态签名生成逻辑
在HTTP请求采样器下添加JSR223预处理程序,语言选择groovy,粘贴以下脚本,替换脚本开头的三个认证参数为你持有的实际值:
// 替换为实际持有参数 def hawkId = "你的Hawk Auth ID" def hawkKey = "你的Hawk Auth Key" def algorithm = "对应Hmac算法名,如HmacSHA256" // 自动读取当前请求配置,无需手动修改 def host = sampler.getDomain() def port = sampler.getPort() def path = sampler.getPath() def method = sampler.getMethod() // 生成符合Hawk规范的动态参数 def timestamp = (System.currentTimeMillis() / 1000).intValue() def nonce = org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(16) // 构造签名字符串,*字段顺序严禁调整* def normalizedStr = """hawk.1.header ${timestamp} ${nonce} ${method} ${path} ${host} ${port} """ // 计算签名 def mac = javax.crypto.Mac.getInstance(algorithm) mac.init(new javax.crypto.spec.SecretKeySpec(hawkKey.getBytes("UTF-8"), algorithm)) def signature = Base64.getEncoder().encodeToString(mac.doFinal(normalizedStr.getBytes("UTF-8"))) // 动态写入Authorization请求头 def authValue = String.format('Hawk id="%s", ts="%s", nonce="%s", mac="%s"', hawkId, timestamp, nonce, signature) sampler.getHeaderManager().add(new org.apache.jmeter.protocol.http.control.Header("Authorization", authValue))
4. 校验与排错
- 添加查看结果树监听器,执行单条请求,检查请求头中的Authorization字段为动态生成值,
ts字段为当前秒级时间戳,与实际时间偏差不超过5分钟(绝大多数Hawk服务端会校验时间偏移量) - 若仍返回401,对比Postman中生成的签名基准字符串:打开Postman该请求的Hawk认证配置页,勾选显示签名详情,对比其生成的标准化字符串与脚本中
normalizedStr的内容是否完全一致,重点排查路径是否包含查询参数、host是否带协议前缀、端口是否匹配。
常见问题排查
- 禁止直接使用Postman导出的固定Authorization头:该值仅在导出时刻的短时间内有效,重复请求、时间窗口过期后都会触发未授权
- 算法名需符合Java加密规范:如算法为SHA256,脚本中需填写
HmacSHA256,遗漏Hmac前缀会导致签名结果完全错误 - 运行JMeter的机器需与服务端时间同步:时间差超过5分钟时,即使签名逻辑正确也会被服务端拦截
- 部分服务端实现会要求签名时包含请求体哈希、APP扩展参数,可在对比Postman签名结构后,对应调整
normalizedStr的拼接内容即可
内容的提问来源于stack exchange,提问作者avidey
相关产品推荐
相关产品推荐

