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。 預設值:無
重要 |
Signature | 字串 | 根據AccessKey Secret和policy計算的簽名資訊,OSS通過簽名資訊驗證POST請求的合法性。更多資訊,請參見PostObject。 預設值:無 重要
|
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
簽名計算過程
建立utf-8編碼的policy。
構造StringToSign。
將policy進行Base64編碼,產生一個安全傳輸的字串,作為待簽名字串(StringToSign)。
計算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=