最近更新时间:2024-06-27 11:33:10
KS3提供V4和V2两种签名方式,推荐使用V4签名方式,参见请求签名V4。
使用KS3 时,可通过 RESTful API 对 KS3 发起 HTTP 匿名请求或 HTTP 签名请求,对于签名请求,KS3服务器端将会对请求发起者进行身份验证。
匿名请求:HTTP 请求不携带任何身份标识和鉴权信息,通过 RESTful API 进行 HTTP 请求操作。当KS3接收到匿名请求时,如果发现用户请求的资源不允许匿名请求,将会返回403错误。
签名请求:HTTP 请求时携带签名,KS3服务器端收到消息后,进行身份验证,验证成功则接受并执行请求,否则将会返回403错误信息并丢弃此请求。
KS3提供了可视化签名工具用于生成V2签名,方便客户调试签名错误,快速定位问题。
用户可以在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等请求头不存在,那么该位置用空串("")来代替。
所有以“x-kss-”为前缀的HTTP请求头被称为CanonicalizedKssHeaders。它的构造方法如下:
将所有以“x-kss-”为前缀的HTTP请求头名字转换成小写字母。如’X-KSS-Meta-Name: Jack’转换成’x-kss-meta-name: Jack。
将上一步得到的所有HTTP请求头按照字典序进行升序排列。
如果有相同名字的请求头,则根据标准RFC 2616, 4.2章进行合并(两个值之间只用逗号分隔)。例如有两个名为’x-kss-meta-name’的请求头,对应的值分别为’ fred’和’ barney’,则合并后为:’x-kss-meta-name:fred,barney’。
删除请求头和内容之间分隔符两端出现的任何空格。如’x-kss-meta-name: fred,barney’转换成:’x-kss-meta-name:fred,barney’。
将所有请求头名称和值用’\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 请求头。
用户发送的请求中,要访问的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构造方法如下:
CanonicalizedResource="/"
如果BucketName不为空,则 CanonicalizedResource = CanonicalizedResource + BucketName + “/”
如果ObjectKey不为空,则 CanonicalizedResource = CanonicalizedResource + ObjectKey
替换CanonicalizedResource中的双斜杠("//")为"/%2F"
如果SubResource不为空,则CanonicalizedResource = CanonicalizedResource + “?” + SubResource
以下是使用V2签名的示例。示例中使用的访问密钥如下:
参数 | 值 |
---|---|
KSSAccessKeyId | AKLTA6qLnuowT6KzKybUQNC0Tw |
KSSSecretAccessKey | OCd5HzFDU1YDUG6eTHASvdt1RRn5bqKNKdl8JxuFrYne+bazX7gmoYUG73XjJ/d2sg== |
从examplebucket中get 对象
请求 | StringToSign |
---|---|
GET /1.txt HTTP/1.1 | GET\n |
注意: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()
向examplebucket中上传一个对象
请求 | StringToSign |
---|---|
PUT /1.txt HTTP/1.1 | PUT\n |
注意: Content-Type请求头包含在请求中,也包含在StringToSign中。但请求中没有Content-MD5请求头,所以StringToSign中是空行。
列出examplebucket中的对象。
请求 | StringToSign |
---|---|
GET /?prefix=1&max-keys=50 HTTP/1.1 | GET\n |
注意:CanonicalizedResource的结尾要有斜杠/,查询字符串为空。
获取examplebucket的访问控制权限配置信息。
请求 | StringToSign |
---|---|
GET /?acl HTTP/1.1 | GET\n |
注意:在CanonicalizedResource中包含子资源查询字符串参数。
从examplebucket中删除对象。bucket在Path中指定,并使用x-kss-date请求头。
请求 | StringToSign |
---|---|
DELETE /examplebucket/1.txt HTTP/1.1 | DELETE\n |
注意:此请求使用x-kss-date请求头来替代Date请求头。
下面的例子在上传对象时,指定了自定义的元数据。
请求 | StringToSign |
---|---|
PUT /1.txt HTTP/1.1 | PUT\n |
注意:“x-kss-”请求头被排序,并转换为小写字符。只有Content-Type, Content-MD5请求头被加入到了StringToSign中,但是其他的Content-*请求头没有被加入。
请求 | StringToSign |
---|---|
GET / HTTP/1.1 | GET\n |
请求 | StringToSign |
---|---|
PUT /%E6%B5%8B%E8%AF%95.txt HTTP/1.1 | PUT\n |
注意:StringToSign中的对象名称被URL编码。
除了将签名信息加入请求头外,用户还可以将签名信息加入到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中包含签名的方法和请求头中包含签名的算法基本一样,主要区别如下:
通过URL包含签名时,之前的Date参数换成Expires参数。
不支持同时在URL和Head中包含签名。
如果传入的Signature,Expires,KSSAccessKeyId出现不止一次,以首次为准。
请求先验证请求时间是否晚于Expires时间:
如果请求时间晚于Expires时间,则返回错误响应码;
如果请求时间不晚于Expires时间,则验证签名。
KS3同时支持KS3 V2和AWS V2签名。
当通过HTTP请求头发送签名时,如果Authorization的值以KSS开头,那么根据KS3 V2进行签名,将x-kss开头的请求头加入签名计算;如果Authorization的值以AWS开头,那么根据AWS V2签名,将x-amz开头的请求头加入签名计算。
当通过URL请求参数发送签名时,如果参数为KSSAccessKeyId,那么根据KS3 V2进行签名;如果参数为AWSAccessKeyId,那么根据AWS V2进行签名。
纯净模式