手写华为云 API 签名连踩三坑:从 APIGW.0301 到 KooCLI 的排障实录

举报
yd_260155359 发表于 2026/10/20 15:29:21 2026/10/20
【摘要】 前言:在写自动化脚本时,我需要用 AK/SK 直接调用华为云 IAM 接口查询账号的 Domain 信息。不想引入庞大的 SDK,决定手写 SDK-HMAC-SHA256 签名。结果半小时内连踩三个坑,最后靠官方 KooCLI 才彻底定位。把踩坑过程记录下来,给同样需要轻量化调用华为云 API 的朋友参考。一、背景:为什么手写签名调用华为云 OpenAPI 有三种方式:完整 SDK、KooC...

前言:在写自动化脚本时,我需要用 AK/SK 直接调用华为云 IAM 接口查询账号的 Domain 信息。不想引入庞大的 SDK,决定手写 SDK-HMAC-SHA256 签名。结果半小时内连踩三个坑,最后靠官方 KooCLI 才彻底定位。把踩坑过程记录下来,给同样需要轻量化调用华为云 API 的朋友参考。

一、背景:为什么手写签名

调用华为云 OpenAPI 有三种方式:完整 SDK、KooCLI(hcloud)、手写签名。我的场景只需要一个 GET 请求,拉个几百字节的 JSON,为了它装几百 MB 的 SDK 不划算。华为云的签名算法文档很清晰:

用 Python 标准库二十行就能实现,看起来很美好。

二、坑一:系统代理是隐形杀手

第一个请求直接炸了:

Python 的 urllib 默认读取系统代理环境变量,而我本机的代理软件对 iam.myhuaweicloud.com 这类国内域名没有直连规则,请求被转发到代理隧道后返回 502。

解法:对国内 API 域名强制绕过代理:

一行代码解决。教训:调试 API 连不通时,先确认请求到底走了哪条路——curl -w "%{remote_ip}" 能看到请求实际打到了 127.0.0.1(代理)。

三、坑二:CanonicalURI 的尾斜杠

修好代理后收到第一个 401,但这次华为云的错误信息非常有价值——它把服务端计算的 canonical_request 原样回显了:

对比后发现:我签的是 /v3/auth/domains,服务端规范化成了 /v3/auth/domains/(带尾斜杠)。把签名串里的 path 补上尾斜杠后重新签名,错误信息里的 canonical_request 与我方逐字符一致——这说明规范化规则对齐了。

四、坑三:签名串一致却依然 401

意外的是:即使 canonical_request 完全一致,签名校验依然失败。这时换思路——装官方 KooCLI 做交叉验证:

结果官方工具一次通过,直接返回了 Domain 信息。同一对凭证,我的实现 401、官方实现 200——结论很明确:手写实现的签名环节仍有未知细节差异(华为云网关重算签名时的输入可能与错误信息里回显的规范化结果并不完全等同),而排查这种"隐形差异"的时间成本,远高于直接用官方工具。

另一个收获:hcloud 的 operation 名称与老文档不同,IAM 域列表接口现在是 KeystoneListAuthDomains(不是 ListAuthDomains);首次运行需要 echo y | hcloud ... 同意隐私声明。

五、总结:三条排障原则

  1. 401 错误信息里的 canonical_request 是金矿——逐字符比对能快速切分"规范化问题"和"签名计算问题";
  1. 先上官方 CLI 交叉验证,再决定要不要手写——如果官方工具也失败,是凭证/账号问题;官方成功而手写失败,果断放弃手写,要么用 CLI 包一层,要么用 SDK 的 signer 模块;
  1. 代理是隐形杀手——国内云 API + 本机代理的组合,第一反应先查请求实际出口。

手写签名的代码我不会删——它留作理解华为云认证机制的教材;但生产脚本里,hcloud + 一层 shell 封装才是最稳的方案。


(完)环境:Windows 11 / Python 3.13 / KooCLI 1.x / 2026-10 实测

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。