Appearance
常见签名认证错误排查
签名认证中常见以下问题,通过如下的排查说明进行一一排查:
不能正确区分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。
生成签名过程中注意事项
- 检查HTTP Method是否正确
- CanonicalURI部分
- 注意前面不需要加host,必须以“/”开头,不以“/”开头的需要补充上,空路径为“/”;
- 注意结尾不该有“/”;
- 注意要做uriEncodeExceptSlash编码。
- CanonicalQueryString部分
- 注意要按字典序进行排序;
- 没有value的key,是否也保留了“=”;
- 没有queryString时,也要在最终的CanonicalRequest中拼接一个\n。
- CanonicalHeaders部分
- 注意这里的header内容,要与实际请求中的header内容完全一致,尤其注意host是否有端口号;
- 实际发出请求中,是否有header被第三方库删除了?
- 签名前缀信息
- timestamp是认证字符串创建时间,不能过早或过晚;
- 输入的SK与AK要对应