阅读124 返回首页    go 搜狐


请求签名__API-Reference_日志服务-阿里云

为保证用户日志数据的安全,Log Service API的所有HTTP请求都必须经过安全验证。目前,该安全验证基于阿里云的访问秘钥,使用对称加密算法完成的。其工作流程如下:

  1. 请求端根据API请求内容(包括HTTP Header和Body)生成签名字符串
  2. 请求端使用阿里云的访问秘钥对(AccessKeyID和AccessKeySecret)对第一步生成的签名字符串进行签名,形成该API请求的数字签名
  3. 请求端把API请求内容和数字签名一同发送给服务端
  4. 服务端在接到请求后会重复如上的第一、二步工作(注:服务端会在后台取得该请求使用的用户访问秘钥对)并在服务端计算出的该请求期望的数字签名
  5. 服务端用期望的数字签名和请求端发送过来的数字签名做比对,如果完全一致则认为该请求通过安全验证。否则直接拒绝该请求。

上面整个流程也可以使用下图直观描述:

通过上面的安全验证流程,可以帮助我们达到如下目的:

  • 确认哪位用户在做API请求。因为在发送请求前需要用户指定生成数字签名的秘钥对,在服务端即可通过该秘钥对确定用户身份,进而可做访问权限管理。
  • 确认用户请求在网络传输过程中有无被篡改。因为服务端会对接收到的请求内容重新计算数字签名,一旦请求内容在网络上被篡改,则无法通过数字签名比对。

签名API请求

为通过API请求的安全验证,用户需要在客户端对其API请求进行签名(即生成正确的数字签名),并且使用HTTP头“Authorization”在网络上传输该请求的数字签名。Authorization头的具体格式如下:

Authorization:LOG <AccessKeyId>:<Signature>

如上格式所示,Authorization头的值包含用户访问秘钥对中的AccessKeyId,且与之对应的AccessKeySecret将用于Signature值的构造。下面将详细解释如何构造该Signature值。

第一步:准备合适的阿里云访问秘钥

如上所述,给API请求生成签名,需使用一对访问秘钥(AccessKeyId/AccessKeySecret)。用户可以使用已经存在的访问秘钥对,也可以创建新的访问秘钥对。但需要保证使用的秘钥对处在“启用”状态。

第二步:生成请求的签名字符串

LOG API的签名字符串由HTTP请求中的Method,Header和Body信息一同生成,具体方式如下:

SignString = VERB + "n"
             + CONTENT-MD5 + "n"
             + CONTENT-TYPE + "n"
             + DATE + "n"
             + CanonicalizedLOGHeaders + "n"
             + CanonicalizedResource

上面公式中的“n"表示换行转义字符,+(加号)表示字符串连接操作,其他各个部分定义如下:

名称 定义 示例
VERB HTTP请求的方法名称 PUT,GET,POST等
CONTENT-MD5 HTTP请求中Body部分的MD5值(必须为大写字母串) 875264590688CA6171F6228AF5BBB3D2
CONTENT-TYPE HTTP请求中Body部分的类型 application/x-protobuf
DATE HTTP请求中的标准时间戳头(遵循RFC 1123格式,使用GMT标准时间) Mon, 3 Jan 2010 08:33:47 GMT
CanonicalizedLOGHeaders 由HTTP请求中以x-log和x-acs为前缀的自定义头构造的字符串(具体构造方法见下面详述) x-log-apiversion:0.6.0nx-log-bodyrawsize:50nx-log-signaturemethod:hmac-sha1
CanonicalizedResource 由HTTP请求资源构造的字符串(具体构造方法见下面详述) /logstores/app_log

对于部分无Body的HTTP请求,其CONTENT-MD5和CONTENT-TYPE两个域为空字符串,这时整个签名字符串的生成方式如下:

SignString = VERB + "n"
             + "n"
             + "n"
             + DATE + "n"
             + CanonicalizedLOGHeaders + "n"
             + CanonicalizedResource

正如公共请求头中描述,LOG API中引入了一个自定义请求头x-log-date。如果用户请求中指定了该请求头,则其值会替代HTTP标准请求头Date加入签名计算。

“CanonicalizedLOGHeaders”的构造方式如下:

1. 将所有以x-log和x-acs为前缀的HTTP请求头的名字转换成小写字母;
2. 将上一步得到的所有LOG自定义请求头按照字典序进行升序排序;
3. 删除请求头和内容之间分隔符两端出现的任何空格;
4. 将所有的头和内容用n分隔符组合成最后的CanonicalizedLOGHeader;

CanonicalizedResource的构造方式如下:

1. 将CanonicalizedResource设置为空字符串("");
2. 放入要访问的LOG资源,如"/logstores/logstorename"(无logstorename则不填);
3. 如请求包含查询字符串(QUERY_STRING),则在CanonicalizedResource字符串尾部添加“?”和查询字符串。

其中QUERY_STRING是URL中请求参数按字典序排序后的字符串,其中参数名和值之间用“=”(等号)相隔组成字符串,并对参数名-值对按照字典序升序排序,然后以’&’符号连接构成字符串。其公式化描述如下:

QUERY_STRING = "KEY1=VALUE1" + "&" + "KEY2=VALUE2"
第三步:生成请求的数字签名

目前,LOG API只支持一种数字签名算法,即默认签名算法"hmac-sha1"。其整个签名公式如下:

Signature = base64(hmac-sha1(UTF8-Encoding-Of(SignString),AccessKeySecret))

签名的方法用RFC 2104中定义的HMAC-SHA1方法 如上公式用的AccessKeySecret必须和最终的Authorization头中使用的AccessKeyId相对应。否则,请求将无法通过服务端验证。

在计算出数字签名后,使用该值按本节最前面描述的Authorization头格式构建完整的LOG API请求安全验证头,并填入HTTP请求中即可发送。

请求签名过程示例

为更好地理解整个请求签名的流程,我们用两个示例来演示整个过程。首先,假设用户用做LOG API签名的访问秘钥对如下:

AccessKeyId = "bq2sjzesjmo86kq35behupbq"
AccessKeySecret = "4fdO2fTDDnZPU/L7CHNdemB2Nsk="
示例一:

用户需要发送如下GET请求列出“ali-test-project”项目下的所有LogStores,其HTTP请求如下:

GET /logstores HTTP 1.1
Mon, 09 Nov 2015 06:11:16 GMT
Host: ali-test-project.cn-hangzhou-devcommon-intranet.sls.aliyuncs.com
x-log-apiversion: 0.6.0
x-log-signaturemethod: hmac-sha1

如上LOG API请求生成的签名字符串为:

GETnnnMon, 09 Nov 2015 06:11:16 GMTnx-log-apiversion:0.6.0nx-log-signaturemethod:hmac-sha1n/logstores?logstoreName=&offset=0&size=1000

由于是GET请求,该请求无任何HTTP Body,所以生成的签名字符串中CONTENT-TYPE与CONTENT-MD5域为空字符串。如果以前面指定的用户AccessKeySecret做签名运算后得到的签名为:

jEYOTCJs2e88o+y5F4/S5IsnBJQ=

最后发送经数字签名的HTTP请求内容如下:

GET /logstores HTTP 1.1
Mon, 09 Nov 2015 06:11:16 GMT
Host: ali-test-project.cn-hangzhou-devcommon-intranet.sls.aliyuncs.com
x-log-apiversion: 0.6.0
x-log-signaturemethod: hmac-sha1
Authorization: LOG bq2sjzesjmo86kq35behupbq:jEYOTCJs2e88o+y5F4/S5IsnBJQ=
示例二:

用户需要给同上例"ali-test-project"项目中名为"test-logstore"的Logstore写入下面日志:

topic=""
time=1447048976
source="10.230.201.117"
"TestKey": "TestContent"

为此,按照LOG API定义需要构建如下HTTP请求:

POST /logstores/test-logstore HTTP/1.1
Date: Mon, 09 Nov 2015 06:03:03 GMT
Host: test-project.cn-hangzhou-devcommon-intranet.sls.aliyuncs.com
x-log-apiversion: 0.6.0
x-log-signaturemethod: hmac-sha1
Content-MD5: 1DD45FA4A70A9300CC9FE7305AF2C494
Content-Length: 52
x-log-apiversion:0.6.0
x-log-bodyrawsize:50
x-log-compresstype:lz4
x-log-signaturemethod:hmac-sha1

<日志内容序列化成ProtoBuffer格式的字节流>

在这个HTTP请求中,写入的日志内容首先被序列化成ProtoBuffer格式(请参考ProtoBuffer格式了解该格式的更多细节)后作为请求Body。所以该请求的Content-Type头的值指定为application/x-protobuf。类似,Content-MD5头的值是请求body对应的MD5值。按照上面的签名字符串构造方式,这个请求对应的签名字符串为:

POSTn1DD45FA4A70A9300CC9FE7305AF2C494napplication/x-protobufnMon, 09 Nov 2015 06:03:03 GMTnx-log-apiversion:0.6.0nx-log-bodyrawsize:50nx-log-compresstype:lz4nx-log-signaturemethod:hmac-sha1n/logstores/test-logstore

同样,以前面示例中的用户AccessKeySecret做签名运算,得到的最终签名为:

XWLGYHGg2F2hcfxWxMLiNkGki6g=

最后发送经数字签名的HTTP请求内容如下:

POST /logstores/test-logstore HTTP/1.1
Date: Mon, 09 Nov 2015 06:03:03 GMT
Host: test-project.cn-hangzhou-devcommon-intranet.sls.aliyuncs.com
x-log-apiversion: 0.6.0
x-log-signaturemethod: hmac-sha1
Content-MD5: 1DD45FA4A70A9300CC9FE7305AF2C494
Content-Length: 52
x-log-apiversion:0.6.0
x-log-bodyrawsize:50
x-log-compresstype:lz4
x-log-signaturemethod:hmac-sha1
Authorization: LOG bq2sjzesjmo86kq35behupbq:XWLGYHGg2F2hcfxWxMLiNkGki6g=

<日志内容序列化成ProtoBuffer格式的字节流>

最后更新:2016-05-06 10:44:22

  上一篇:go 公共响应头__API-Reference_日志服务-阿里云
  下一篇:go 通用错误码__API-Reference_日志服务-阿里云