Skip to content
大纲

常见签名认证错误排查

签名认证中常见以下问题,通过如下的排查说明进行一一排查:

不能正确区分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,因此传送的签名也有问题。

URI尾部的"/"不一致

客户端请求:

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

构造验签请求时,误将URI多写了尾部的"/":

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

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

Host头域端口不一致

客户端请求:

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

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

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

用错了aksk

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

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

生成签名过程中注意事项

  1. 检查HTTP Method是否正确
  2. CanonicalURI部分
    • 注意前面不需要加host,必须以“/”开头,不以“/”开头的需要补充上,空路径为“/”;
    • 注意结尾不该有“/”;
    • 注意要做uriEncodeExceptSlash编码。
  3. CanonicalQueryString部分
    • 注意要按字典序进行排序;
    • 没有value的key,是否也保留了“=”;
    • 没有queryString时,也要在最终的CanonicalRequest中拼接一个\n。
  4. CanonicalHeaders部分
    • 注意这里的header内容,要与实际请求中的header内容完全一致,尤其注意host是否有端口号;
    • 实际发出请求中,是否有header被第三方库删除了?
  5. 签名前缀信息
    • timestamp是认证字符串创建时间,不能过早或过晚;
    • 输入的SK与AK要对应