用户可以在HTTP请求中增加Authorization(授权)的Header来包含签名信息,表明这个消息已被授权。如果用户的请求中没有Authentication字段,则认为是匿名访问。
验证码计算方法如下:
Authorization: "AWS " + AccessKeyID + ":" + Signature
Signature =Base64( HMAC-SHA1( SecretAccessKey, UTF-8-Encoding-Of( StringToSign ) ) ) ;
StringToSign = HTTP-VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedAmzHeaders +"\n" +
CanonicalizedResource;
CanonicalizedAmzHeaders = [详见下列描述];
CanonicalizedResource = [ "/" + Bucket ] +
<HTTP-Request-URI > +
[<sub-resource>]
注 :sub-resource如果存在,可参与签名的参数包括:acl、torrent、logging、location、policy、requestPayment、versioning、versions、versionId、notification、uploadId、uploads、partNumber、website、delete、lifecycle、tagging、cors、restore、inventory。
HMAC-SHA1是由RFC 2104定义的算法。该算法需要输入两个字符串:一个key和一个message。OOS在验证请求时,使用您的SecretAccessKey作为key,使用UTF-8编码的StringToSign作为message。HMAC-SHA1的输出同样是个字符串,被称为摘要。Signature请求参数是这个摘要的Base64编码。
说明
Content-MD5表示请求内容数据的MD5值。
Content-Type表示请求内容的类型。
Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式。
CanonicalizedAmzHeaders表示http中的object user meta组合。
CanonicalizedResource表示用户要访问的OOS资源。
使用Base64编码
HMAC请求签名必须使用Base64编码。Base64编码将签名转换为简单的能附加到请求中的ASCII编码字符串。加号和斜杠这两个字符不能直接在URL中使用,必须经过编码。比如,如果授权编码包括加号,在URL中把它编码成为%2B。
StringToSign
StringToSign中不包含Content-Type, Date, Content-MD5这些请求头的名字,只包含这些请求头的值。但是以“x-amz”开头的请求头的名字和值都包含在StringToSign中。
如果在请求中,Content-Type, Content-MD5等请求头不存在,那么该位置用空串("")来代替。
时间戳说明
在签名时必须使用时间戳,可以用HTTP的Date请求头,也可以用x-amz-date请求头。时间戳中的时间和OOS的系统时间不能相差15分钟以上,否则,OOS会返回错误码RequestTimeTooSkewed。
有些HTTP客户端不能设置Date请求头,如果你在签名时设置Date请求头有困难,那么你可以使用x-amz-date请求头来传送时间戳。x-amz-date请求头需要符合RFC 2616 的格式 。当请求中包含x-amz-date头时,OOS在计算签名时会忽略Date头。所以如果请求中有x-amz-date头,在客户端计算签名时,Date头的值应设置为空串。
构建CanonicalizedAMZHeaders的方法
所有以“x-amz-”为前缀的HTTP Header被称为CanonicalizedAMZHeaders。它的构建方法如下:
- 将所有以“x-amz-”为前缀的HTTP请求头的名字转换成小写字母。如’X-AMZ-Meta-Name: fred’转换成’x-amz-meta-name: fred。
- 将上一步得到的所有HTTP请求头按照字典序进行升序排列。
- 如果有相同名字的请求头,则根据标准RFC 2616, 4.2章进行合并(两个值之间只用英文逗号分隔)。如有两个名为'x-amz-meta-name'的请求头,对应的值分别为'fred'和'barney',则合并后为:'x-amz-meta-name:fred,barney'。
- 删除分隔符(:)两端和值两端出现的任何空格。如'x-amz-meta-name : fred '转换成:'x-amz-meta-name:fred'。
- 将所有的头和内容用’\n’分隔符分隔拼成最后的CanonicalizedAMZHeader。
构建CanonicalizedResource的方法
用户发送请求中访问的OOS目标资源被称为CanonicalizedResource。它的构建方法如下:
- 将CanonicalizedResource置成空字符串(“”)。
- 如果请求通过Host请求头来指定Bucket,那么增加Bucket名,并在其前面加上“/”(例如/BucketName)。对于Bucket名称在path中的请求,或者没有指定Bucket的请求,不做任何操作。
- 在path中增加未编码的HTTP 请求URI,到请求参数处截止,不包含请求参数。
- 如果请求包含子资源,例如?acl, ?website, ?logging,那么将所有的子资源按照字典序,从小到大排列并以’&’为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加“?”和子资源字符串。在构造CanonicalizedResource时,必须包含的子资源,OOS支持的子资源包括:acl、torrent、logging、location、policy、requestPayment、versioning、versions、versionId、notification、uploadId、uploads、partNumber、website、delete、lifecycle、tagging、cors、restore、inventory。
如果请求通过参数指定了要覆盖的响应头,那么在CanonicalizedResource后加上该请求参数和值。当进行签名时,不要对这些值进行编码。但是当发送请求的时候,用户必须对这些参数值进行编码。GET请求中的这些参数包括:response-content-type,response-content-language, response-expires, response-cache-control,response-content-disposition, response-content-encoding。例如:/BucketName/ObjectName?response-content-type=ContentType
当发送批量删除文件请求时,delete参数需要包含在CanonicalizedResource中。
示例
以下是使用V2签名的示例,示例中使用的访问密钥如下:
参数 | 值 |
---|---|
AccessKeyID | 3a7451ae6b635b4f5ded |
SecretAccessKey | c458417af3507ca686128f54efb3a00d5ad7ff09 |
GET Object
从名为example-bucket的Bucket中get文件。
请求 | StringToSign |
---|---|
GET /photos/puppy.jpg HTTP/1.1 Host: example-bucket.oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 01:32:55 GMT Content-Type: application/octet-stream Authorization: AWS 3a7451ae6b635b4f5ded:icJnqU3Zfm1sEOBCBwJPKymwWds= |
GET\n \n application/octet-stream\n Tue, 11 Jun 2024 01:32:55 GMT\n /example-bucket/photos/puppy.jpg |
注意CanonicalizedResource中包含Bucket名称,但是HTTP请求URI中没有,因为Bucket名称是在Host请求头中指定的。请求中没有Content-MD5请求头,所以StringToSign中是空行。
PUT Object
向名为example-bucket的Bucket中上传一个文件。
请求 | StringToSign |
---|---|
PUT /photos/puppy.jpg HTTP/1.1 Host: example-bucket.oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 01:43:59 GMT Content-Type: image/jpeg Content-MD5: ICy5YqxZB1uWSwcVLSNLcA== Content-Length: 94328 Authorization: AWS 3a7451ae6b635b4f5ded:MHUV0HaL8UiNe/VPNbWg06PppEI= |
PUT\n ICy5YqxZB1uWSwcVLSNLcA==\n image/jpeg\n Tue, 11 Jun 2024 01:43:59 GMT\n /example-bucket/photos/puppy.jpg |
注意Content-Type、Content-MD5请求头包含在请求中,也包含在StringToSign中。
List Objects
list名为example-bucket的Bucket的文件。
请求 | StringToSign |
---|---|
GET /?prefix=photos&max-keys=50&marker=puppy HTTP/1.1 Host: example-bucket.oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 01:59:59 GMT Content-Type: application/octet-stream User-Agent: Mozilla/5.0 Authorization: AWS 3a7451ae6b635b4f5ded:kitekL1v232x7FYLUUi7y2kPC9g= |
GET\n \n application/octet-stream\n Tue, 11 Jun 2024 01:59:59 GMT\n /example-bucket/ |
注意CanonicalizedResource的结尾要有斜杠/,查询字符串为空。
获取ACL
下面的例子是获取名为example-bucket的Bucket的访问控制权限配置信息。
请求 | StringToSign |
---|---|
GET /?acl HTTP/1.1 Host: example-bucket.oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 02:06:03 GMT Content-Type: application/octet-stream Authorization: AWS 3a7451ae6b635b4f5ded:7x+mp5y3YFS6BC9pdPiqsevbjb4= |
GET\n \n application/octet-stream\n Tue, 11 Jun 2024 02:06:03 GMT\n /example-bucket/?acl |
注意在CanonicalizedResource中是如何包含子资源查询字符串参数的。
Delete Object
从名为example-bucket的Bucket中删除文件。Bucket在path中指定,并使用x-amz-date请求头。
请求 | StringToSign |
---|---|
DELETE /example-bucket/photos/puppy.jpg HTTP/1.1 Host: oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 06:47:39 GMT x-amz-date: Tue, 11 Jun 2024 06:37:21 GMT Authorization: AWS 3a7451ae6b635b4f5ded:0kgBoDiPB3sQAy+Ole+oKcH+QRE= |
DELETE\n \n \n \n x-amz-date:Tue, 11 Jun 2024 06:37:21 GMT\n /example-bucket/photos/puppy.jpg |
注意此请求使用x-amz-date请求头来替代Date请求头,在StringToSign中,实际的Date请求头被设置成空行。
使用CNAME形式上传文件
下面的例子通过CNAME 形式上传文件,并使用自定义元数据。其中:Bucket为example-bucket,Bucket绑定的自定义域名为oos11.ctyun.cn。
请求 | StringToSign |
---|---|
PUT /example-bucket/db-backup.dat.gz HTTP/1.1 Host: oos11.ctyun.cn Date: Tue, 11 Jun 2024 07:18:11 GMT content-type: application/x-download Content-MD5: ICy5YqxZB1uWSwcVLSNLcA== X-Amz-Meta-ReviewedBy: joe X-Amz-Meta-FileChecksum: 0x02661779 X-Amz-Meta-ChecksumAlgorithm: crc32 Content-Disposition: attachment; file name=database.dat Content-Encoding: gzip Content-Length: 3 Authorization: AWS 3a7451ae6b635b4f5ded:Wdqh0EKuT5lUZioWfc0rk2a6Arg= |
PUT\n ICy5YqxZB1uWSwcVLSNLcA==\n application/x-download\n Tue, 11 Jun 2024 07:18:11 GMT\n x-amz-meta-checksumalgorithm:crc32\n x-amz-meta-filechecksum:0x02661779\n x-amz-meta-reviewedby:joe\n /example-bucket/db-backup.dat.gz |
注意“x-amz -”请求头被排序了,空白行被删除,转换为小写字符,多个同名的请求头使用逗号分隔的方式被加入。只有Content-Type, Content-MD5请求头被加入到了StringToSign中,但是其他的Content-*请求头没有被加入。
List Buckets
请求 | StringToSign |
---|---|
GET / HTTP/1.1 Host: oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 03:35:03 GMT Authorization: AWS 3a7451ae6b635b4f5ded:MTxKel9VvMQGamBD1gQXJ5ttm5c= |
GET\n \n \n Tue, 11 Jun 2024 03:35:03 GMT\n / |
文件名被编码
请求 | StringToSign |
---|---|
GET /dictionary/fran/123%E5%92%8C123 HTTP/1.1 Host: example-bucket.oos-cn.ctyunapi.cn Date: Tue, 11 Jun 2024 05:35:27 GMT Authorization: AWS 3a7451ae6b635b4f5ded:owSmnJIMATp1GdDpXtw72QXJ7x0= |
GET\n \n \n Tue, 11 Jun 2024 05:35:27 GMT\n /example-bucket/dictionary/fran/123%E5%92%8C123 |
StringToSign中从请求URI获取的元素,是按原样获取的,包括URL编码和大小写。