849
阿裏雲
在Header中包含簽名__訪問控製_API 參考_對象存儲 OSS-阿裏雲
用戶可以在HTTP請求中增加 Authorization
的Header來包含簽名(Signature)信息,表明這個消息已被授權。
Authorization字段計算的方法
Authorization = "OSS " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
VERB + "n"
+ Content-MD5 + "n"
+ Content-Type + "n"
+ Date + "n"
+ CanonicalizedOSSHeaders
+ CanonicalizedResource))
AccessKeySecret
表示簽名所需的密鑰VERB
表示HTTP 請求的Method,主要有PUT,GET,POST,HEAD,DELETE等n
表示換行符Content-MD5
表示請求內容數據的MD5值,對消息內容(不包括頭部)計算MD5值獲得128比特位數字,對該數字進行base64編碼而得到。該請求頭可用於消息合法性的檢查(消息內容是否與發送時一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以為空。詳情參看RFC2616 Content-MD5Content-Type
表示請求內容的類型,如”application/octet-stream”,也可以為空Date
表示此次操作的時間,且必須為GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT”CanonicalizedOSSHeaders
表示以 x-oss- 為前綴的http header的字典序排列CanonicalizedResource
表示用戶想要訪問的OSS資源
其中,Date和CanonicalizedResource不能為空;如果請求中的Date時間和OSS服務器的時間差15分鍾以上,OSS服務器將拒絕該服務,並返回HTTP 403錯誤。
構建CanonicalizedOSSHeaders的方法
所有以 x-oss- 為前綴的HTTP Header被稱為CanonicalizedOSSHeaders。它的構建方法如下:
- 將所有以 x-oss- 為前綴的HTTP請求頭的名字轉換成 小寫 。如
X-OSS-Meta-Name: TaoBao
轉換成x-oss-meta-name: TaoBao
。 - 如果請求是以STS獲得的AccessKeyId和AccessKeySecret發送時,還需要將獲得的security-token值,以
x-oss-security-token:security-token
的形式加入到簽名字符串中。 - 將上一步得到的所有HTTP請求頭按照名字的字典序進行升序排列。
- 刪除請求頭和內容之間分隔符兩端出現的任何空格。如
x-oss-meta-name: TaoBao
轉換成:x-oss-meta-name:TaoBao
。 - 將每一個頭和內容用
n
分隔符分隔拚成最後的CanonicalizedOSSHeaders。
注意:
- CanonicalizedOSSHeaders可以為空,無需添加最後的
n
。- 如果隻有一個,則如
x-oss-meta-an
,注意最後的n
。- 如果有多個,則如
x-oss-meta-a:anx-oss-meta-b:bnx-oss-meta-c:cn
, 注意最後的”n”。
構建CanonicalizedResource的方法
用戶發送請求中想訪問的OSS目標資源被稱為CanonicalizedResource。它的構建方法如下:
- 將CanonicalizedResource置成空字符串
""
; - 放入要訪問的OSS資源
/BucketName/ObjectName
(無ObjectName則CanonicalizedResource為”/BucketName/“,如果同時也沒有BucketName則為“/”) - 如果請求的資源包括子資源(SubResource) ,那麼將所有的子資源按照字典序,從小到大排列並以
&
為分隔符生成子資源字符串。在CanonicalizedResource字符串尾添加?
和子資源字符串。此時的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId
- 如果用戶請求在指定了查詢字符串(QueryString,也叫Http Request Parameters),那麼將這些查詢字符串及其請求值按照 字典序,從小到大排列,以
&
為分隔符,按參數添加到CanonicalizedResource中。此時的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId
。
提示:
- OSS目前支持的子資源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等
- 子資源(sub-resource)有三種類型:
- 資源標識,如子資源中的acl,append,uploadId,symlink等,詳見關於Bucket的操作和關於Object的操作
- 指定返回Header字段,如
response-***
,詳見 GetObject的Request Parameters
- 文件(Object)處理方式,如
x-oss-process
,用於文件的處理方式,如圖片處理
計算簽名頭規則
- 簽名的字符串必須為
UTF-8
格式。含有中文字符的簽名字符串必須先進行UTF-8
編碼,再與AccessKeySecret
計算最終簽名。 - 簽名的方法用RFC 2104中定義的HMAC-SHA1方法,其中Key為 ccessKeySecret` 。
Content-Type
和Content-MD5
在請求中不是必須的,但是如果請求需要簽名驗證,空值的話以換行符n
代替。- 在所有非HTTP標準定義的header中,隻有以
x-oss-
開頭的header,需要加入簽名字符串;其他非HTTP標準header將被OSS忽略(如上例中的x-oss-magic是需要加入簽名字符串的)。 - 以
x-oss-
開頭的header在簽名驗證前需要符合以下規範:- header的名字需要變成小寫。
- header按字典序自小到大排序。
- 分割header name和value的冒號前後不能有空格。
- 每個Header之後都有一個換行符“n”,如果沒有Header,CanonicalizedOSSHeaders就設置為空。
簽名示例
假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV”
請求 | 簽名字符串計算公式 | 簽名字符串 |
---|---|---|
PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra |
Signature = base64(hmac-sha1(AccessKeySecret, VERB + “n” + Content-MD5 + “n” + Content-Type + “n” + Date + “n” + CanonicalizedOSSHeaders + CanonicalizedResource)) |
“PUTn eB5eJF1ptWaXm4bijSPyxw==n text/htmln Thu, 17 Nov 2005 18:49:58 GMTn x-oss-magic:abracadabranx-oss-meta-author:foo@bar.comn /oss-example/nelson” |
可用以下方法計算簽名(Signature):
python示例代碼:
import base64
import hmac
import sha
h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV",
"PUTnODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=ntext/htmlnThu, 17 Nov 2005 18:49:58 GMTnx-oss-magic:abracadabranx-oss-meta-author:foo@bar.comn/oss-example/nelson", sha)
Signature = base64.b64encode(h.digest())
print("Signature: %s" % Signature)
簽名(Signature)計算結果應該為 26NBxoKdsyly4EDv6inkoDft/yA=,因為Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最後Authorization為 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然後加上Authorization頭來組成最後需要發送的消息:
PUT /nelson HTTP/1.0
Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=
Content-Md5: eB5eJF1ptWaXm4bijSPyxw==
Content-Type: text/html
Date: Thu, 17 Nov 2005 18:49:58 GMT
Host: oss-example.oss-cn-hangzhou.aliyuncs.com
X-OSS-Meta-Author: foo@bar.com
X-OSS-Magic: abracadabra
細節分析
- 如果傳入的AccessKeyId不存在或inactive,返回403 Forbidden。錯誤碼:InvalidAccessKeyId。
- 若用戶請求頭中Authorization值的格式不對,返回400 Bad Request。錯誤碼:InvalidArgument。
- OSS所有的請求都必須使用HTTP 1.1協議規定的GMT時間格式。其中,日期的格式為:
date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)
上述日期格式中,“天”所占位數都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 - 如果簽名驗證的時候,頭中沒有傳入Date或者格式不正確,返回403 Forbidden錯誤。錯誤碼:AccessDenied。
- 傳入請求的時間必須在OSS服務器當前時間之後的15分鍾以內,否則返回403 Forbidden。錯誤碼:RequestTimeTooSkewed。
- 如果AccessKeyId是active的,但OSS判斷用戶的請求發生簽名錯誤,則返回403 Forbidden,並在返回給用戶的response中告訴用戶正確的用於驗證加密的簽名字符串。用戶可以根據OSS的response來檢查自己的簽名字符串是否正確。返回示例:
<?xml version="1.0" ?>
<Error>
<Code>
SignatureDoesNotMatch
</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
<StringToSignBytes>
47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c
</StringToSignBytes>
<RequestId>
1E446260FF9B10C2
</RequestId>
<HostId>
oss-cn-hangzhou.aliyuncs.com
</HostId>
<SignatureProvided>
y5H7yzPsA/tP4+0tH1HHvPEwUv8=
</SignatureProvided>
<StringToSign>
GET
Wed, 11 May 2011 07:59:25 GMT
/oss-example?acl
</StringToSign>
<OSSAccessKeyId>
AKIAIVAKMSMOY7VOMRWQ
</OSSAccessKeyId>
</Error>
提示:
- OSS SDK已經實現簽名,用戶使用OSS SDK不需要關注簽名問題。如果您想了解具體語言的簽名實現,請參考OSS SDK的代碼。OSS SDK簽名實現的文件如下表:
SDK 簽名實現 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java
- 當您自己實現簽名,訪問OSS報
SignatureDoesNotMatch
錯誤時,請使用 可視化簽名工具 確認簽名並排除錯誤。
常見問題
Content-MD5的計算方法
Content-MD5的計算
以消息內容為"123456789"來說,計算這個字符串的Content-MD5
正確的計算方式:
標準中定義的算法簡單點說就是:
1. 先計算MD5加密的二進製數組(128位)。
2. 再對這個二進製進行base64編碼(而不是對32位字符串編碼)。
以Python為例子:
正確計算的代碼為:
>>> import base64,hashlib
>>> hash = hashlib.md5()
>>> hash.update("0123456789")
>>> base64.b64encode(hash.digest())
'eB5eJF1ptWaXm4bijSPyxw=='
需要注意
正確的是:hash.digest(),計算出進製數組(128位)
>>> hash.digest()
'xx1e^$]ixb5fx97x9bx86xe2x8d#xf2xc7'
常見錯誤是直接對計算出的32位字符串編碼進行base64編碼。
例如,錯誤的是:hash.hexdigest(),計算得到可見的32位字符串編碼
>>> hash.hexdigest()
'781e5e245d69b566979b86e28d23f2c7'
錯誤的MD5值進行base64編碼後的結果:
>>> base64.b64encode(hash.hexdigest())
'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='
最後更新:2016-12-12 16:44:23
上一篇:
用戶簽名驗證__訪問控製_API 參考_對象存儲 OSS-阿裏雲
下一篇:
在URL中包含簽名__訪問控製_API 參考_對象存儲 OSS-阿裏雲
阿裏雲棲大會上,何止千億投資達摩院
查詢分析__應用高級配置_產品使用手冊_開放搜索-阿裏雲
遊戲盾___產品功能說明_產品常見問題_DDoS 高防IP-阿裏雲
錯誤編碼:HSF-0002__HSF 常見問題_開發常見問題_產品常見問題_企業級分布式應用服務 EDAS-阿裏雲
主機重啟遷移幫助文檔__網站上傳/下載_使用指南_雲虛機主機-阿裏雲
取消安全組規則__安全組_用戶指南_雲服務器 ECS-阿裏雲
查詢媒體工作流__媒體工作流接口_API使用手冊_視頻點播-阿裏雲
項目(Project)__基礎概念_用戶指南_日誌服務-阿裏雲
三分鍾創建完整伸縮方案__快速入門_彈性伸縮-阿裏雲
免費版和高級版區別__產品簡介_數據管理-阿裏雲
相關內容
常見錯誤說明__附錄_大數據計算服務-阿裏雲
發送短信接口__API使用手冊_短信服務-阿裏雲
接口文檔__Android_安全組件教程_移動安全-阿裏雲
運營商錯誤碼(聯通)__常見問題_短信服務-阿裏雲
設置短信模板__使用手冊_短信服務-阿裏雲
OSS 權限問題及排查__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲
消息通知__操作指南_批量計算-阿裏雲
設備端快速接入(MQTT)__快速開始_阿裏雲物聯網套件-阿裏雲
查詢API調用流量數據__API管理相關接口_API_API 網關-阿裏雲
使用STS訪問__JavaScript-SDK_SDK 參考_對象存儲 OSS-阿裏雲