常见签名认证错误排查

相关参考 Reference

  • 文档有奖反馈活动
  • 文档有奖反馈2
  • 功能发布记录
  • 捉虫活动获奖名单
  • 鉴权认证机制
    • 常见签名认证错误排查
    • 简介
    • 在URL中包含认证字符串
    • 在Header中包含认证字符串
    • 签名流程
    • Sample-Code
    • 生成V2认证字符串
    • 错误码
    • 生成认证字符串
  • SDK入门指南
    • Python-SDK帮助指南
    • PHP-SDK入门指南
    • Java-SDK入门指南
  • 区域选择说明
    • 区域
    • 可用区
  • API SDK
    • Java-SDK
  • 证书管理
    • 多用户访问控制
    • 管理证书
    • 格式转换
    • 简介
    • Python-SDK
    • GO-SDK
    • 上传证书
    • 证书和私钥
    • API参考
    • 常见问题
    • 第三方机构创建证书
    • 证书替换
    • JAVA-SDK
  • 企业组织
    • 退出组织
    • 账户联合认证(SSO)
    • 权限策略管理
    • 子账户管理
    • 产品介绍
    • 财务管理
    • 常见问题
    • 企业组织vs多用户访问控制
    • 权限评估逻辑
    • 创建企业组织
    • 系统限制
    • 组织单元
    • API参考
      • 通用说明
      • 企业组织管理接口
      • 邀请管理接口
      • 策略管理接口
      • 简介
      • 单元管理接口
      • 账户管理接口
      • 数据类型
  • API Key
    • 操作手册
    • 简介
    • API参考
  • 获取AKSK
    • 简介
    • 如何获取AKSK
  • 术语表
    • B
    • Z
    • F
    • G
    • C
    • H
    • P
    • L
    • T
    • M
    • I
    • Q
    • N
    • V
    • J
    • R
    • K
    • S
    • O
    • W
    • D
    • X
    • A
    • Y
    • E
所有文档
menu
没有找到结果,请重新输入

相关参考 Reference

  • 文档有奖反馈活动
  • 文档有奖反馈2
  • 功能发布记录
  • 捉虫活动获奖名单
  • 鉴权认证机制
    • 常见签名认证错误排查
    • 简介
    • 在URL中包含认证字符串
    • 在Header中包含认证字符串
    • 签名流程
    • Sample-Code
    • 生成V2认证字符串
    • 错误码
    • 生成认证字符串
  • SDK入门指南
    • Python-SDK帮助指南
    • PHP-SDK入门指南
    • Java-SDK入门指南
  • 区域选择说明
    • 区域
    • 可用区
  • API SDK
    • Java-SDK
  • 证书管理
    • 多用户访问控制
    • 管理证书
    • 格式转换
    • 简介
    • Python-SDK
    • GO-SDK
    • 上传证书
    • 证书和私钥
    • API参考
    • 常见问题
    • 第三方机构创建证书
    • 证书替换
    • JAVA-SDK
  • 企业组织
    • 退出组织
    • 账户联合认证(SSO)
    • 权限策略管理
    • 子账户管理
    • 产品介绍
    • 财务管理
    • 常见问题
    • 企业组织vs多用户访问控制
    • 权限评估逻辑
    • 创建企业组织
    • 系统限制
    • 组织单元
    • API参考
      • 通用说明
      • 企业组织管理接口
      • 邀请管理接口
      • 策略管理接口
      • 简介
      • 单元管理接口
      • 账户管理接口
      • 数据类型
  • API Key
    • 操作手册
    • 简介
    • API参考
  • 获取AKSK
    • 简介
    • 如何获取AKSK
  • 术语表
    • B
    • Z
    • F
    • G
    • C
    • H
    • P
    • L
    • T
    • M
    • I
    • Q
    • N
    • V
    • J
    • R
    • K
    • S
    • O
    • W
    • D
    • X
    • A
    • Y
    • E
  • 文档中心
  • arrow
  • 相关参考Reference
  • arrow
  • 鉴权认证机制
  • arrow
  • 常见签名认证错误排查
本页目录
  • 不能正确区分URL中的URI部分和QueryString部分
  • URI尾部的"/"不一致
  • Host头域端口不一致
  • x-bce-date头的问题
  • 用错了ak/sk
  • 客户基于StsCredential来请求但服务未正确传递security_token
  • 生成签名过程中注意事项

常见签名认证错误排查

更新时间:2025-08-22

签名认证中常见以下问题,你可以配合签名排查工具在线排查签名问题,或者通过如下的排查说明进行一一排查:

  • 不能正确区分URL中的URI部分和QueryString部分
  • URI尾部的"/"不一致
  • Host头域端口不一致
  • x-bce-date头的问题
  • 用错了ak/sk
  • 客户基于StsCredential来请求但服务未正确传递security_token
  • 生成签名过程中注意事项

不能正确区分URL中的URI部分和QueryString部分

假设请求的URL是/v1/settings/region/list?type=public,此处URI应该为/v1/settings/region/list,type=public是querystring。但是客户端并没有正确区分它们,在计算签名时把/v1/settings/region/list?type=public都当成了PATH,进而得到的CanonicalRequest,因此传送的签名也有问题。 而服务端在验证签名使用的

Plain Text
1	# 客户端请求的CanonicalRequest:
2	GET
3	/v1/settings/region/list%3ftype%3dpublic
4	host:settings.bce-internal.baidu.com
5	x-bce-date:2017-02-15T08%3A52%3A48Z

服务端向IAM构造验签请求时,传递的是正确的URI和QueryString部分:

Plain Text
1	{
2	  "auth" : {
3	    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59",
4	    "request" : {
5	      "method" : "GET",
6	      "uri" : "/v1/settings/region/list",
7	      "headers" : {
8	        "host" : "settings.bce-internal.baidu.com",
9	        "x-bce-date": "2017-02-15T08:52:48Z"
10	      },
11	      "params": {
12	        "type": "public"
13	      }
14	    }
15	  }

进而,IAM基于服务提供的请求信息,演算签名时URI与客户端不一致,得到的签名必然与请求值不一致。

URI尾部的"/"不一致

客户端请求:

Plain Text
1	# 客户端请求的CanonicalRequest:
2	GET
3	/v1/settings/region/list
4	host:settings.bce-internal.baidu.com
5	x-bce-date:2017-02-15T08%3A52%3A48Z

服务端向IAM构造验签请求时,误将URI多写了个尾部的"/":

Plain Text
1	{
2	  "auth" : {
3	    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59",
4	    "request" : {
5	      "method" : "GET",
6	      "uri" : "/v1/settings/region/list/", #尾部多了个'/'
7	      "headers" : {
8	        "host" : "settings.bce-internal.baidu.com",
9	        "x-bce-date": "2017-02-15T08:52:48Z"
10	      }
11	    }
12	  }

进而,IAM基于服务提供的请求信息,演算签名时URI与客户端不一致,得到的签名必然与请求值不一致。

Host头域端口不一致

客户端请求:

Plain Text
1	# 客户端请求的CanonicalRequest:
2	GET
3	/v1/settings/region/list
4	host:settings.bce-internal.baidu.com%3A80
5	x-bce-date:2017-02-15T08%3A52%3A48Z

服务端向IAM构造验签请求时,host字段并没有加上端口:

Plain Text
1	{
2	  "auth" : {
3	    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/2671990529b9c46c95e688f1a2809db185c608ee3716a731a8fdde6bb2028d84",
4	    "request" : {
5	      "method" : "GET",
6	      "uri" : "/v1/settings/region/list/",
7	      "headers" : {
8	        "host" : "settings.bce-internal.baidu.com", #host并没带端口
9	        "x-bce-date": "2017-02-15T08:52:48Z"
10	      }
11	    }
12	  }

host不一致,得到的签名必然与请求值不一致。

x-bce-date头的问题

默认情况(authorization中未指明SignedHeaders时)x-bce-date会参与签名。客户端需要保证:计算签名时的此域,与最终发出请求时的此域,二者保持一致。

如,计算签名时使用的时间是 2017-02-15T08:52:48Z

Plain Text
1	GET
2	/v1/settings/region/list
3	host:settings.bce-internal.baidu.com
4	x-bce-date:2017-02-15T08%3A52%3A48Z

但发出请求时,x-bce-date 变成了 2017-02-15T08:52:49Z

Plain Text
1	GET /v1/settings/region/list HTTP/1.1
2	User-Agent: curl/7.33.0
3	Host: settings.bce-internal.baidu.com
4	Accept: */*
5	authorization: bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date;x-bce-request-id/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59
6	x-bce-date: 2017-02-15T08:52:49Z

IAM演算签名时x-bce-date域与客户端不一致,得到的签名必然与请求值不一致。

用错了ak/sk

以下两种情况容易出现低级的错误导致签名不通过:

  • 基于配置的程序,配置中ak对了,但sk却存在错误。这种情况IAM并不会返回ak不存在,而是签名错误。一个特点是signningKey与IAM演算的不一致。
  • 自动从API拿到的ak/sk,但是构造业务client时却传错了,比如构造参数可能分别是ak和sk,但代码调用时两个参数都使用了ak。

客户基于StsCredential来请求但服务未正确传递security_token

客户端请求:

Plain Text
1# 客户端请求的CanonicalRequest:
2GET
3/v1/settings/region/list
4host:settings.bce-internal.baidu.com
5x-bce-date:2017-02-15T08%3A52%3A48Z
6x-bce-security-token: ZGZiM2M3MmU4Mjk4NGQ2MGEzYTNhYTAyMDE3NTZmZmV8AAAA...

服务端向IAM构造验签请求时,没有将security_token提取出来,放到专门的字段,用于周知IAM客户使用了临时credential:

Plain Text
1{
2  "auth" : {
3    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59",
4    "request" : {
5      "method" : "GET",
6      "uri" : "/v1/settings/region/list",
7      "headers" : {
8        "host" : "settings.bce-internal.baidu.com",
9        "x-bce-date": "2017-02-15T08:52:48Z",
10        "x-bce-security-token": "ZGZiM2M3MmU4Mjk4NGQ2MGEzYTNhYTAyMDE3NTZmZmV8AAAA..."
11      }
12    }
13  }

IAM不知道签名为临时ak/sk签出,从长效ak/sk表中查找不到相应的ak,于是会报"Could not find credential"。

生成签名过程中注意事项

  1. 检查HTTP Method是否正确
  2. CanonicalURI部分

    • 注意前面不需要加host,必须以“/”开头,不以“/”开头的需要补充上,空路径为“/”;
    • 注意结尾不该有“/”;
    • 注意要做uriEncodeExceptSlash编码。
  3. CanonicalQueryString部分

    • 注意要按字典序进行排序;
    • 没有value的key,是否也保留了“=”;
    • 没有queryString时,也要在最终的CanonicalRequest中拼接一个\n。
  4. CanonicalHeaders部分

    • 百度智能云默认的signedHeaders:Host、Content-Length、Content-Type、Content-MD5、所有以 x-bce- 开头的Header;
    • 注意这里的header内容,要与实际请求中的header内容完全一致,尤其注意host是否有端口号,x-bce-date是否有变化;
    • 实际发出请求中,是否有header被第三方库删除了?
    • 如果请求中{signedHeaders}字段留空,那么是否完全按照百度智能云默认的signedHeaders计算的?
  5. 签名前缀信息

    • timestamp是认证字符串创建时间,不能过早或过晚;
    • 输入的SK与AK要对应

上一篇
捉虫活动获奖名单
下一篇
简介