全部產品
Search
文件中心

Object Storage Service:POST V1簽名

更新時間:Jul 30, 2024

POST簽名是指在使用PostObject上傳方式時,為保證上傳請求的安全性,OSS要求每個上傳請求都攜帶一個簽名(Signature)。在POST V1簽名中,Signature是通過存取金鑰(AccessKey Secret)對一系列請求參數(包括上傳策略policy、到期時間等)進行加密計算得出。應用伺服器產生簽名後,將其與上傳策略policy等資訊一併提供給用戶端,用戶端使用這些資訊構造上傳請求。OSS收到上傳請求後會驗證簽名的有效性,只有簽名驗證通過的請求會被接受,簽名驗證未通過的請求將被拒絕。

重要

OSS支援更安全的V4簽名演算法,建議您使用V4簽名。更多資訊,請參見V4簽名

POST簽名介紹

HTTP POST請求支援使用V1簽名演算法,表單和policy扮演著關鍵角色,用於確保上傳請求的安全性和合規性。

表單

表單是POST請求中實際攜帶的欄位集合,用於傳遞檔案本身及其相關的中繼資料資訊。以下是POST V1簽名專屬的表單元素,其他公用表單元素,請參見PostObject表單元素

欄位

類型

描述

OSSAccessKeyId

字串

存取金鑰中的AccessKey ID。

預設值:無

    重要
    • 當Bucket ACL為公用讀取或者私人時,必須提供OSSAccessKeyId表單域。

    • 在已存在Signature、policy表單域的情況下,必須提供OSSAccessKeyId表單域。

Signature

字串

根據AccessKey Secret和policy計算的簽名資訊,OSS通過簽名資訊驗證POST請求的合法性。更多資訊,請參見PostObject

預設值:無

重要
  • 當Bucket ACL為公用讀取或者私人時,必須提供Signature表單域。

  • 在已存在OSSAccessKeyId、policy表單域的情況下,必須提供Signature表單域。

  • 該表單域的Key大小寫不敏感,但表單域的Value值大小寫敏感。

policy

policy表單域是一種安全性原則,用於定義使用者通過HTML表單上傳檔案到OSS時的許可權限制和約束條件。policy表單域通過JSON格式定義,通過多項參數限制上傳操作,例如允許上傳的Bucket名稱、Object首碼、有效期間、允許的HTTP方法、上傳內容的大小限制、內容類型限制等。

重要

policy中必須包含expiration和conditions欄位。

{
  "expiration": "2023-12-03T13:00:00.000Z",
  "conditions": [
    {"bucket": "examplebucket"},
    ["content-length-range", 1, 10],
    ["eq", "$success_action_status", "201"],
    ["starts-with", "$key", "user/eric/"],
    ["in", "$content-type", ["image/jpg", "image/png"]],
    ["not-in", "$cache-control", ["no-cache"]]
  ]
}

policy詳細說明如下:

  • expiration

    用於指定policy的到期時間,以ISO8601 GMT時間表示。例如指定為2023-12-03T13:00:00.000Z,表示必須在2023年12月03日13點之前發起POST請求。

  • conditions

    用於指定POST請求表單域的合法值。

    欄位

    類型

    是否必選

    描述

    Conditions匹配方式

    bucket

    字串

    Bucket名稱。

    bucket

    content-length-range

    字串

    上傳Object的最小和最大允許大小,單位為位元組。

    content-length-range

    success_action_status

    字串

    上傳成功後的返回狀態代碼。

    eq、starts-with、in和not-in

    key

    字串

    上傳的Object名稱。

    eq、starts-with、in和not-in

    content-type

    字串

    限制上傳的檔案類型。

    eq、starts-with、in和not-in

    cache-control

    字串

    指定Object的緩衝行為。

    eq、starts-with、in和not-in

Conditions匹配方式

Conditions匹配方式

描述

content-length-range

指定所允許上傳的檔案最大和最小範圍,例如允許的檔案大小為1~10位元組,則可以寫為["content-length-range", 1, 10]。

eq

表單域的值必須精確匹配Conditions中聲明的值。例如指定key表單域的值必須為a:{"key": "a"} ,則可以寫為["eq", "$key", "a"]。

starts-with

表單域的值必須以指定首碼開始。例如,如果要指定key的值以user/user1開始,則可以寫為["starts-with", "$key", "user/user1"]。

in

以字串列表的形式指定需包含的檢查元素。例如通過PostObject介面上傳圖片時,需校正上傳的檔案為圖片類型,但允許多種格式的圖片,則通過in語義指定為["in", "$content-type", ["image/jpg", "image/png"]]。

not-in

以字串列表的形式指定需排除的檢查元素。例如通過PostObject介面上傳時需要指定Object緩衝行為,且不支援no-cache的形式,則通過not-in語義指定為["not-in", "$cache-control", ["no-cache"]]。

policy逸出字元

在Post policy中$表示變數。如果要描述$,需要使用逸出字元\$。下表描述了在Post policy的JSON中需要進行轉義的字元。

逸出字元

描述

\/

斜杠

\\

反斜線

\”

雙引號

\$

美元符

\b

空格

\f

換頁

\n

換行

\r

斷行符號

\t

水平定位字元

\uxxxx

Unicode字元

簽名計算過程

  1. 建立utf-8編碼的policy。

  2. 構造StringToSign。

    將policy進行Base64編碼,產生一個安全傳輸的字串,作為待簽名字串(StringToSign)。

  3. 計算Signature。

    使用AccessKeySecret對要簽名的字串進行簽名,簽名方法為Signature = base64(hmac-sha1(AccessKeySecret,base64(policy)))

POST簽名計算完整範例程式碼

以上述提供的policy為例,通過Java範例程式碼示範POST簽名計算的完整過程。

import org.apache.commons.codec.binary.Base64;

public class Demo {
    public static void main(String[] args) {
        // 運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_SECRET。
        String accessKeySecret =  System.getenv().get("OSS_ACCESS_KEY_SECRET");

        // 步驟1:建立policy。
        String policy = "{\n" +
                "  \"expiration\": \"2023-12-03T13:00:00.000Z\",\n" +
                "  \"conditions\": [\n" +
                "    {\"bucket\": \"examplebucket\"},\n" +
                "    [\"content-length-range\", 1, 10],\n" +
                "    [\"eq\", \"$success_action_status\", \"201\"],\n" +
                "    [\"starts-with\", \"$key\", \"user/eric/\"],\n" +
                "    [\"in\", \"$content-type\", [\"image/jpg\", \"image/png\"]],\n" +
                "    [\"not-in\", \"$cache-control\", [\"no-cache\"]]\n" +
                "  ]\n" +
                "}";

        // 步驟2:構造待簽名字串(StringToSign)。
        String stringToSign = new String(Base64.encodeBase64(policy.getBytes()));

        // 步驟3:計算Signature。
        String signature = com.aliyun.oss.common.auth.ServiceSignature.create().computeSignature(accessKeySecret, stringToSign);
        System.out.println("signature:" + signature);
    }
}

返回結果如下:

signature:hR2cJnoG9uzrZLDAmrfOtUjtkSM=