请求签名V2

最近更新时间:2021-12-06 16:30:27

查看PDF

KS3提供V4和V2两种签名方式,推荐使用V4签名方式,参见请求签名V4

使用KS3 时,可通过 RESTful API 对 KS3 发起 HTTP 匿名请求或 HTTP 签名请求,对于签名请求,KS3服务器端将会对请求发起者进行身份验证。

  • 匿名请求:HTTP 请求不携带任何身份标识和鉴权信息,通过 RESTful API 进行 HTTP 请求操作。当KS3接收到匿名请求时,如果发现用户请求的资源不允许匿名请求,将会返回403错误。
  • 签名请求:HTTP 请求时携带签名,KS3服务器端收到消息后,进行身份验证,验证成功则接受并执行请求,否则将会返回403错误信息并丢弃此请求。
    KS3提供了可视化签名工具用于生成V2签名,方便客户调试签名错误,快速定位问题。

通过HTTP请求头发送签名

用户可以在HTTP请求中增加Authorization请求头来包含签名信息。

签名计算方法

"Authorization: KSS" + YourAccessKey + ":" + Signature

Signature =Base64( HMAC-SHA1( YourSecretAccessKey, UTF-8-Encoding-Of( StringToSign ) ) ) ;

StringToSign = HTTP-VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n"   +
CanonicalizedKssHeaders + "\n"
CanonicalizedResource;

CanonicalizedResource = [ "/" + Bucket ] +
<HTTP-Request-URI > +
[<sub-resource>];

说明:

  • HTTP-Verb 表示请求的方法,如:GET\PUT\POST\DELETE等
  • Content-MD5 表示请求内容数据的MD5值, 使用Base64编码。当请求头中包含Content-MD5时,需要在StringToSign中包含Content-MD5,否则用("")替代。

注意:
Content-MD5的算法为先对数据做MD5摘要,再将MD5摘要做Base64编码,中间不需要做Hex编码。由于部分语言或工具包的MD5是默认做Hex编码的,所以当MD5算出来的结果为Hex编码时,首先需要对算出来的结果做Hex解码,然后再做Base64编码。详解RFC2616

  • Content-Type 表示请求体的类型
  • Date 表示此次请求操作的时间,必须为 HTTP1.1 中支持的 GMT 格式,例如:Tue, 30 Nov 2021 06:29:38 GMT。若Date时间与KS3服务端时间相差15分钟以上,则KS3将返回403错误。

注意:
有的客户端不支持发送Date请求头。这种情况下,计算签名时需要保持Date字段的同时,在CanonicalizedKssHeaders中加入x-kss-date,格式与Date一致。当请求中包含x-kss-date头时,KS3在计算签名时会忽略Date头。

  • CanonicalizedKssHeaders 表示HTTP请求中的以x-kss开头的Header组合,详见
    CanonicalizedKssHeaders计算方法
  • CanonicalizedResource 表示用户访问的资源,详见CanonicalizedResource的计算方法
  • StringToSign中不包含Content-Type, Date, Content-MD5这些请求头的名字,只包含这些请求头的值。但是以“x-kss”开头的请求头的名字和值都包含在StringToSign中。
  • 如果在请求中,Content-Type, Content-MD5等请求头不存在,那么该位置用空串("")来代替。

CanonicalizedKssHeaders计算方法

所有以“x-kss-”为前缀的HTTP请求头被称为CanonicalizedKssHeaders。它的构造方法如下:

  1. 将所有以“x-kss-”为前缀的HTTP请求头名字转换成小写字母。如’X-KSS-Meta-Name: Jack’转换成’x-kss-meta-name: Jack。

  2. 将上一步得到的所有HTTP请求头按照字典序进行升序排列。

  3. 如果有相同名字的请求头,则根据标准RFC 2616, 4.2章进行合并(两个值之间只用逗号分隔)。例如有两个名为’x-kss-meta-name’的请求头,对应的值分别为’ fred’和’ barney’,则合并后为:’x-kss-meta-name:fred,barney’。

  4. 删除请求头和内容之间分隔符两端出现的任何空格。如’x-kss-meta-name: fred,barney’转换成:’x-kss-meta-name:fred,barney’。

  5. 将所有请求头名称和值用’\n’分隔符分隔,拼成最后的CanonicalizedKssHeaders。

注意:

  • 若CanonicalizedKssHeaders为空,无需添加最后的\n。
  • 如果只有一个请求头,则需要在最后添加\n,例如:x-kss-meta-yourname:Lee\n
  • 如果有多个请求头,则使用使用"\n"分隔符连接在一起,并且在最后添加\n,例如:x-kss-meta-myname:Jack\nx-kss-meta-yourname:Lee\n
  • 如果客户端不支持发送 Date 请求头,则在计算CanonicalizedKssHeaders时必须增加 x-kss-date 请求头。

构建CanonicalizedResource的方法

用户发送的请求中,要访问的KS3目标资源被称为CanonicalizedResource。结构如下:

/[BucketName/[ObjectKey[?SubResource]]]
  • BucketName: 用户请求的Bucket名称。

  • ObjectKey: 用户请求的Object名称,需要对Object名称做URL编码。

  • SubResource: 用户请求的子资源。把URL参数中的"acl",“lifecycle”,“location”,“logging”,“notification”,“partNumber”,“policy”,“requestPayment”,“torrent”,“uploadId”,“uploads”,“versionId”,“versioning”,“versions”,“website”,“delete”,“thumbnail”,“cors”,“queryadp”,“adp”,“asyntask”,“querytask”,“domain”,“response-content-type”,“response-content-language”,“response-expires”,“response-cache-control”,“response-content-disposition”,"response-content-encoding"筛选出来,将这些查询字符串及其请求值(不做URL编码的请求值)按照字典序,从小到大排列,以&为分隔符排列,即可得到SubResource。

CanonicalizedResource构造方法如下:

  1. CanonicalizedResource="/"

  2. 如果BucketName不为空,则 CanonicalizedResource = CanonicalizedResource + BucketName + “/”

  3. 如果ObjectKey不为空,则 CanonicalizedResource = CanonicalizedResource + ObjectKey

  4. 替换CanonicalizedResource中的双斜杠("//")为"/%2F"

  5. 如果SubResource不为空,则CanonicalizedResource = CanonicalizedResource + “?” + SubResource

示例

以下是使用V2签名的示例。示例中使用的访问密钥如下:

参数
AWSAccessKeyId AKLTA6qLnuowT6KzKybUQNC0Tw
AWSSecretAccessKey OCd5HzFDU1YDUG6eTHASvdt1RRn5bqKNKdl8JxuFrYne+bazX7gmoYUG73XjJ/d2sg==
GET Object

从examplebucket中get 对象

请求 StringToSign
GET /1.txt HTTP/1.1
Host: examplebucket.ks3-cn-beijing.ksyuncs.com
Date: Tue, 30 Nov 2021 11:06:30 GMT
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:i+PiOc1sxIe6yjZwyi4/+kxmXs8=
GET\n
\n
\n
Tue, 30 Nov 2021 11:06:30 GMT\n
/examplebucket/1.txt

注意:CanonicalizedResource中包含bucket名称,但是HTTP请求URI中没有,因为bucket名称是在Host请求头中指定的。

示例代码如下:

import base64
import hmac
from hashlib import sha1
h = hmac.new("OCd5HzFDU1YDUG6eTHASvdt1RRn5bqKNKdl8JxuFrYne+bazX7gmoYUG73XjJ/d2sg==", "GET\n\n\nTue, 30 Nov 2021 11:06:30 GMT\n/examplebucket/photos/1.jpg", sha1)
Signature = base64.encodestring(h.digest()).strip()
PUT Object

向examplebucket中上传一个对象

请求 StringToSign
PUT /1.txt HTTP/1.1
Content-Type: text/plain
Content-Length: 10
Host: examplebucket.ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 01:46:43 GMT
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:k53X6xtOlzOz9lQDYY/IA3NGVrY=

[data]
PUT\n
\n
text/plain\n
Wed, 1 Dec 2021 01:46:43 GMT\n
/examplebucket/1.txt

注意: Content-Type请求头包含在请求中,也包含在StringToSign中。但请求中没有Content-MD5请求头,所以StringToSign中是空行。

List Objects

列出examplebucket中的对象。

请求 StringToSign
GET /?prefix=1&max-keys=50 HTTP/1.1
Host: examplebucket.ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 01:51:57 GMT
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:VpjIPQFR7PuTYnbZ1Xp/BrEgBSw=
GET\n
\n
\n
Wed, 1 Dec 2021 01:51:57 GMT\n
/examplebucket/

注意:CanonicalizedResource的结尾要有斜杠/,查询字符串为空。

获取ACL

获取examplebucket的访问控制权限配置信息。

请求 StringToSign
GET /?acl HTTP/1.1
Host: examplebucket.ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 01:56:35 GMT
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:97ppTrAzwsJn5vYwCHajNWnq7Mw=
GET\n
\n
\n
Wed, 1 Dec 2021 01:56:35 GMT\n
/examplebucket/?acl

注意:在CanonicalizedResource中包含子资源查询字符串参数。

Delete Object

从examplebucket中删除对象。bucket在Path中指定,并使用x-kss-date请求头。

请求 StringToSign
DELETE /examplebucket/1.txt HTTP/1.1
Host: ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 03:39:18 GMT
x-kss-date: Wed, 1 Dec 2021 03:39:18 GMT
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:jUOKm9QlcWxLiR9BNw13+FlHKuw=
DELETE\n
\n
\n
Wed, 1 Dec 2021 03:39:18 GMT\n
x-kss-date:Wed, 1 Dec 2021 03:39:18 GMT\n
/examplebucket/1.txt

注意:此请求使用x-kss-date请求头来替代Date请求头。

使用自定义元数据上传对象

下面的例子在上传对象时,指定了自定义的元数据。

请求 StringToSign
PUT /1.txt HTTP/1.1
Host: examplebucket.ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 06:26:05 GMT
X-Kss-Acl: public-read
Content-Type: text/plain
Content-MD5: u7iq5XwQTNpAyThDrV5tuA==
X-Kss-Meta-key1: value1
X-Kss-Meta-key2: value2
X-Kss-Meta-key2: value3
Content-Disposition: attachment
Content-Length: 10
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:vK9Ng6vkG6bJWk3HDYby6Q0OeBw=

[data]
PUT\n
u7iq5XwQTNpAyThDrV5tuA==
text/plain\n
Wed, 1 Dec 2021 06:26:05 GMT\n
x-kss-acl:public-read\n
x-kss-meta-key1:value1\n
x-kss-meta-key2:value2\n
/examplebucket/1.txt

注意:“x-kss-”请求头被排序,并转换为小写字符。只有Content-Type, Content-MD5请求头被加入到了StringToSign中,但是其他的Content-*请求头没有被加入。

List Buckets
请求 StringToSign
GET / HTTP/1.1
Host: ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 06:29:04 GMT
Authorization: KSS AKLTA6qLnuowT6KzKybUQNC0Tw:G8TTlgydlSkLIgSyG6kYP+IcF+A=
GET\n
\n
\n
Wed, 1 Dec 2021 06:29:04 GMT\n
/
对象名被编码
请求 StringToSign
PUT /%E6%B5%8B%E8%AF%95.txt HTTP/1.1
Host: examplebucket.ks3-cn-beijing.ksyuncs.com
Date: Wed, 1 Dec 2021 06:32:40 GMT
Authorization: AWS 7799e793ce4624ee7e5a:dxhSBHoI6eVSPcXJqEghlUzZMnY=
PUT\n
\n
text/plain\n
Wed, 1 Dec 2021 06:32:40 GMT\n
/examplebucket/%E6%B5%8B%E8%AF%95.txt

注意:StringToSign中的对象名称被URL编码。

通过 URL QueryString 发送签名

除了将签名信息加入请求头外,用户还可以将签名信息加入到URL查询参数中。这样就可以通过浏览器直接访问对象数据。

注意:使用URL签名方式时,有将您授权的数据在过期时间内暴露在互联网上的风险,建议您预先评估后再使用。

URL中包含签名的示例如下:

http://examplebucket.ks3-cn-beijing.ksyuncs.com/1.txt?KSSAccessKeyId=AKLTA6qLnuowT6KzKybUQNC0Tw&Expires=1638345010&Signature=0INTzi%2FDcz2sjL6O6LCnc00U05E%3D 

注意:在URL中实现签名,必须至少包含Signature,Expires,KSSAccessKeyId三个参数。

请求参数

请求参数名称 示例中的值 描述
KSSAccessKeyId AKLTA6qLnuowT6KzKybUQNC0Tw 用户的AccessKeyId,获取方式参见获取AK/SK
Expires 1638345010 签名过期时间,是UNIX时间,即自1970 年 1 月 1 日 00:00:00 UTC 以来的秒数。 如果KS3接收到URL请求的时间晚于签名中包含的Expires参数,则返回请求超时的错误码。
Signature 0INTzi%2FDcz2sjL6O6LCnc00U05E%3D 计算后的签名

URL中包含签名的方法和请求头中包含签名的算法基本一样,主要区别如下:

  1. 通过URL包含签名时,之前的Date参数换成Expires参数。

  2. 不支持同时在URL和Head中包含签名。

  3. 如果传入的Signature,Expires,KSSAccessKeyId出现不止一次,以第一次为准。

  4. 请求先验证请求时间是否晚于Expires时间:

  • 如果请求时间晚于Expires时间,则返回错误响应码;
  • 如果请求时间不晚于Expires时间,则验证签名。

与AWS S3的兼容性

KS3同时支持KS3 V2和AWS V2签名。

  • 当通过HTTP请求头发送签名时,如果Authorization的值以KSS开头,那么根据KS3 V2进行签名,将x-kss开头的请求头加入签名计算;如果Authorization的值以AWS开头,那么根据AWS V4签名,将x-amz开头的请求头加入签名计算。
  • 当通过URL请求参数发送签名时,如果参数为KSSAccessKeyId,那么根据KS3 V2进行签名;如果参数为AWSAccessKeyId,那么根据AWS V2进行签名。

文档内容是否对您有帮助?

根本没帮助
文档较差
文档一般
文档不错
文档很好

在文档使用中是否遇到以下问题

内容不全,不深入
内容更新不及时
描述不清晰,比较混乱
系统或功能太复杂,缺乏足够的引导
内容冗长

更多建议

0/200

评价建议不能为空

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

问题反馈