除了使用Authorization Header,您還可以在URL中加入簽名信息,以便將該URL轉給第三方實現授權訪問。

注意事項

  • 使用在URL中簽名的方式,會將授權的數據在過期時間內曝露在互聯網上,請預先評估使用風險。
  • OSS不支持同時在URLHeader中包含簽名。
  • PUTGET請求都支持在URL中簽名。
  • 您可以為PUT操作生成一個預簽名的URL,該URL檢查用戶是否上傳了正確的內容。SDK對請求進行預簽名時,將計算請求正文的校驗和,并生成包含在預簽名URL中的MD5校驗和。用戶必須上傳與SDK生成的MD5校驗和相同的內容,否則操作失敗。如果要驗證MD5,只需在請求中增加Content-MD5頭即可。

簽名實現

  • 簽名示例
    https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2pc56s936****&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv****
    如果需要使用STS用戶構造URL簽名,則必須攜帶security-token。
    https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2pc56s936****&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv****&security-token=CAISowJ1q6Ft5B2yfSjIr5bgIOz31blR9oWmWBfCs3kDR/xm3Imc1zz2IHxMdHJsCeAcs/Q0lGFR5/sflqJIRoReREvCUcZr8szfWcsZos2T1fau5Jko1be0ewHKeQKZsebWZ+LmNpy/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/kFC9MMRVuAcCZhDtVbLRcYgq18D3bKMuu3ORPHm3fZCFES2jBxkmRi86+ysIP+phPVlw/90fRH5dazcJW0Zsx0OJo6Wcq+3+FqM6DQlTNM6hwNtoUO1fYUommb54nDXwQIvUjfbtC5qIM/cFVLAYEhALNBofTGkvl1h/fejYyfyWwWYbkFCHiPFNr9kJCUSbr4a4sjF6zyPnPWycyCLYXleLzhxPWd/2kagAGaXG69BqwYNvrKKI3W8weP3bNc1wQDMXQfiHpFCRG6lYhh3iXFtpwH90A3sTlxzRGvi8+9p63JwrluOHWs+Fj6S6s0cOhKvKRWYE8UuWeXIvv4l6DAGwHDE8BLjLC11f5prUJgI2wb+3hwuBod32Jx+us/1p996Glao725orcb****

    您可以在簽名URL中添加想要授權的IP地址、IP地址段或VPC ID,避免未授權的終端訪問OSS資源。

    https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?&OSSAccessKeyId=44CF9590006BF252F707&Expires=1475462111&Signature=OjxkTUbT6rXCZcW8QhvlrXQr8vsP80EFdo6oG5qsBx****&x-oss-ac-subnet-mask=32
  • 參數說明
    名稱類型是否必選描述
    OSSAccessKeyId字符串指定URL簽名中使用的AccessKey ID。
    Expires數字Unix時間戳(自UTC時間19700101號開始的秒數),用于標識該URL的超時時間,單位為秒。如果OSS接收到該URL請求的時間晚于簽名中包含的Expires參數時,則返回請求超時的錯誤碼。例如,當前時間是1141889060,開發者希望創建一個60秒后自動失效的URL,則可以設置Expires時間為1141889120。
    說明 出于安全考慮,OSS控制臺中默認URL的有效時間為3600秒,最大值為32400秒。關于修改URL超時時間的具體操作,請參見分享文件。
    Signature字符串簽名信息。格式如下:
    Signature = urlencode(base64(hmac-sha1(AccessKeySecret,
              VERB + "\n" 
              + CONTENT-MD5 + "\n" 
              + CONTENT-TYPE + "\n" 
              + EXPIRES + "\n" 
              + CanonicalizedOSSHeaders
              + CanonicalizedResource)))
    • 所有OSS支持的請求和各種Header參數,在URL中進行簽名的算法和在Header中包含簽名的算法類似。
    • 生成URL中的簽名字符串時,除了將Date參數替換為Expires參數外,仍然包含CONTENT-TYPE、CONTENT-MD5、CanonicalizedOSSHeadersHeader中包含簽名中定義的Header(請求中雖然仍有Date請求Header,但無需將Date加入簽名字符串中)。
    • URL中包含簽名時必須對URL進行編碼。如果在URL中多次傳入Signature、ExpiresOSSAccessKeyId,則以第一次傳入的值為準。
    • 使用URL簽名時,OSS會先驗證請求時間是否晚于Expires時間,然后再驗證簽名。
    security-token字符串安全令牌。只有當使用STS用戶構造URL簽名時,才需要設置此參數。
    說明 關于搭建STS服務的具體操作,請參見使用STS臨時訪問憑證訪問OSS。您可以通過調用STS服務的AssumeRole接口或者使用各語言STS SDK來獲取臨時訪問憑證。臨時訪問憑證包括臨時訪問密鑰(AccessKey IDAccessKey Secret)和安全令牌(SecurityToken)。
    x-oss-ac-source-ip字符串指定IP地址或者IP地址段。如果在生成簽名時添加了IP地址或IP地址段,則需要添加參數x-oss-ac-subnet-mask,用于標記子網掩碼。
    x-oss-ac-subnet-mask數字子網掩碼中1的個數。如果請求中帶有該參數,OSS會將實際請求IP地址與子網掩碼進行求與,然后用于計算簽名是否正確。如果該參數被惡意竄改,將導致簽名無法校驗通過。
    x-oss-ac-vpc-id字符串指定VPC ID。指定該參數后,OSS會判斷是否為對應VPC ID來源的請求。如果請求是從該VPC ID發起且該參數已賦值,則同時校驗VPC ID和來源IP地址或IP地址段。
    x-oss-ac-forward-allow布爾型指定是否允許轉發請求。OSS如果檢測到該字段并且請求中帶有X-Forwarded-For(可能為多個IP地址),則將X-Forwarded-For的值用于計算簽名校驗。
    取值如下:
    • true:表示允許轉發請求。
      重要 設置為true存在請求頭被篡改劫持的風險。
    • false(默認值):不允許轉發請求。
  • 生成簽名的Python示例代碼
    • 示例一(只涉及必選參數)
      import base64
      import hmac
      import hashlib
      import urllib
      h = hmac.new("accesskey",
                   "GET\n\n\n1141889120\n/examplebucket/oss-api.pdf",
                   hashlib.sha1)
      urllib.quote(base64.encodestring(h.digest()).strip())
    • 示例二(包含可選參數)
      • 簽名時,需按照字典序升序排列可選的簽名參數。如果參數未配置則為空。
      • 當您需要指定具體IP地址訪問時,只需在生成簽名時添加IP地址(例如x-oss-ac-source-ip=127.0.0.1),并在query參數中提供子網掩碼用于計算簽名(例如x-oss-ac-subnet-mask=32)。
      import base64
      import hmac
      import hashlib
      import urllib
      h = hmac.new(accesskey,
                   "GET\n\n\n1141889120\n%2Fexamplebucket%2Foss-api.pdf?\
                   &x-oss-ac-forward-allow=true\
                   &x-oss-ac-source-ip=127.0.0.1\
                   &x-oss-ac-subnet-mask=32\
                   &x-oss-signature-version=OSS2",
                   hashlib.sha256)
      Signature = base64.encodestring(h.digest()).strip()

SDK示例

下表提供各語言SDK生成簽名URL的方法以及通過簽名URL上傳或下載文件的示例。

SDKURL簽名方法GitHub示例簽名URL使用示例
Java SDKOSSClient.generatePresignedUrlAuthorizedAccessSample.javaJava
Python SDKBucket.sign_urlsts.pyPython
PHP SDKOssClient.signUrlSignature.phpPHP
Node.js SDKUrlsignatureUrl.jsNode.js
Browser.js SDKUrlsignatureUrl.jsBrowser.js
Android SDKOSSClient.presignConstrainedObjectURLOSSClient.javaAndroid
iOS SDKpresignConstrainURLWithBucketName:withObjectKey:httpMethod:withExpirationInterval:withParametersOSSClient.hiOS
Go SDKsignURLsign_url.goGo
C SDKoss_gen_signed_urloss_object.cC
C++ SDKOssClient::GeneratePresignedUrlOssClient.ccC++
.Net SDKOssClient.GeneratePresignedUriUrlSignatureSample.cs.NET

錯誤碼

錯誤碼返回消息描述
AccessDenied403 ForbiddenURL中添加簽名時,Signature、ExpiresOSSAccessKeyId順序可以調換,但缺少Signature、ExpiresOSSAccessKeyId中的一個或者多個。
AccessDenied403 Forbidden訪問的當前時間晚于請求中設定的Expires時間或時間格式錯誤。
InvalidArgument400 Bad RequestURL中包含Signature、Expires、OSSAccessKeyId中的一個或者多個,并且Header中也包含簽名消息。