除了使用Authorization Head,用戶還可以在URL中加入簽名資訊,這樣用戶就可以把該URL轉給第三方實現授權訪問

實現方式

URL簽名樣本:

http://oss-example.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2pc56s936**9l&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D

URL簽名,必須至少包含SignatureExpiresOSSAccessKeyId三個參數。

  • Expires 這個參數的值是一個UNIX時間(自UTC時間1970年1月1號開始的秒數,詳見Wikipedia),用於標識該URL的逾時時間。如果OSS接收到這個URL請求的時候晚於簽名中包含的Expires參數時,則返回請求逾時的錯誤碼。例如:目前時間是1141889060,開發人員希望建立一個60秒後自動失效的URL,則可以設定Expires時間為1141889120。
  • OSSAccessKeyId 即密鑰中的AccessKeyId。
  • Signature 表示簽名資訊。所有的OSS支援的請求和各種Header參數,在URL中進行簽名的演算法和在Header中包含簽名的演算法基本一樣。
    Signature = urlencode(base64(hmac-sha1(AccessKeySecret,
              VERB + "\n" 
              + CONTENT-MD5 + "\n" 
              + CONTENT-TYPE + "\n" 
              + EXPIRES + "\n" 
              + CanonicalizedOSSHeaders
              + CanonicalizedResource)))

    其中,與header中包含簽名相比主要區別如下:

    • 通過URL包含簽名時,之前的Date參數換成Expires參數。
    • 不支援同時在URL和Head中包含簽名。
    • 如果傳入的Signature,Expires,OSSAccessKeyId出現不止一次,以第一次為準。
    • 請求先驗證請求時間是否晚於Expires時間,然後再驗證簽名。
    • 將簽名字元串放到url時,注意要對url進行urlencode
  • 臨時用戶URL簽名時,需要攜帶security-token,格式如下:
    http://oss-example.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2pc56s936**9l&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D&security-token=SecurityToken

範例程式碼

URL中添加簽名的python範例程式碼:

import base64
import hmac
import sha
import urllib
h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV",
             "GET\n\n\n1141889120\n/oss-example/oss-api.pdf",
             sha)
urllib.quote (base64.encodestring(h.digest()).strip())
说明
  • 上面為python的範例程式碼。
  • OSS SDK中提供了提供URL簽名的方法,使用方法請參看SDK檔案中的授權訪問章節。
  • OSS SDK的URL簽名實現,請參看下錶:
    SDK URL簽名方法 實現檔案
    Java SDK OSSClient.generatePresignedUrl OSSClient.java
    Python SDK Bucket.sign_url api.py
    .Net SDK OssClient.GeneratePresignedUri OssClient.cs
    PHP SDK OssClient.signUrl OssClient.php
    JavaScript SDK signatureUrl object.js
    C SDK oss_gen_signed_url oss_object.c

細節分析

  • 使用在URL中籤名的方式,會將你授權的數據在過期時間以內曝露在互連網上,請預先評估使用風險。
  • PUT和GET請求都支援在URL中籤名。
  • 在URL中添加簽名時,Signature,Expires,OSSAccessKeyId順序可以交換,但是如果Signature,Expires,OSSAccessKeyId缺少其中的一個或者多個,返回403 Forbidden。錯誤碼:AccessDenied。
  • 如果訪問的目前時間晚於請求中設定的Expires時間,返回403 Forbidden。錯誤碼:AccessDenied。
  • 如果Expires時間格式錯誤,返回403 Forbidden。錯誤碼:AccessDenied。
  • 如果URL中包含參數Signature,Expires,OSSAccessKeyId中的一個或者多個,並且Head中也包含簽名消息,返回消息400 Bad Request。錯誤碼:InvalidArgument。
  • 生成簽名字元串時,除Date被替換成Expires參數外,仍然包含content-type、content-md5等上節中定義的Header(請求中雖然仍然有Date這個要求標頭,但不需要將Date加入簽名字元串中)。