用戶可以在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.daliqc.cn。
| 請求 | StringToSign |
|---|---|
| PUT /example-bucket/db-backup.dat.gz HTTP/1.1 Host: oos11.daliqc.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編碼和大小寫。