常见签名认证错误排查
所有文档

          相关参考 Reference

          常见签名认证错误排查

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

          不能正确区分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,因此传送的签名也有问题。 而服务端在验证签名使用的

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

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

          	{
          	  "auth" : {
          	    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59",
          	    "request" : {
          	      "method" : "GET",
          	      "uri" : "/v1/settings/region/list",
          	      "headers" : {
          	        "host" : "settings.bce-internal.baidu.com",
          	        "x-bce-date": "2017-02-15T08:52:48Z"
          	      },
          	      "params": {
          	        "type": "public"
          	      }
          	    }
          	  }

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

          URI尾部的"/"不一致

          客户端请求:

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

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

          	{
          	  "auth" : {
          	    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59",
          	    "request" : {
          	      "method" : "GET",
          	      "uri" : "/v1/settings/region/list/", #尾部多了个'/'
          	      "headers" : {
          	        "host" : "settings.bce-internal.baidu.com",
          	        "x-bce-date": "2017-02-15T08:52:48Z"
          	      }
          	    }
          	  }

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

          Host头域端口不一致

          客户端请求:

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

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

          	{
          	  "auth" : {
          	    "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/2671990529b9c46c95e688f1a2809db185c608ee3716a731a8fdde6bb2028d84",
          	    "request" : {
          	      "method" : "GET",
          	      "uri" : "/v1/settings/region/list/",
          	      "headers" : {
          	        "host" : "settings.bce-internal.baidu.com", #host并没带端口
          	        "x-bce-date": "2017-02-15T08:52:48Z"
          	      }
          	    }
          	  }

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

          x-bce-date头的问题

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

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

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

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

          	GET /v1/settings/region/list HTTP/1.1
          	User-Agent: curl/7.33.0
          	Host: settings.bce-internal.baidu.com
          	Accept: */*
          	authorization: bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date;x-bce-request-id/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59
          	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

          客户端请求:

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

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

          {
            "auth" : {
              "authorization" : "bce-auth-v1/f3e1f5c2ef9c4d25b7f8b936861cd175/2017-04-05T08:29:50Z/3600/host;x-bce-date/9a48ec83ffb6c486892c4985df7dc6bc20f7c7bebb483f8f355592b8503a3f59",
              "request" : {
                "method" : "GET",
                "uri" : "/v1/settings/region/list",
                "headers" : {
                  "host" : "settings.bce-internal.baidu.com",
                  "x-bce-date": "2017-02-15T08:52:48Z",
                  "x-bce-security-token": "ZGZiM2M3MmU4Mjk4NGQ2MGEzYTNhYTAyMDE3NTZmZmV8AAAA..."
                }
              }
            }

          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要对应
          上一篇
          Sample-Code
          下一篇
          错误码