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
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"]]。 |
在Post policy中$表示變量。如果要描述$,需要使用轉義字符\$。下表描述了在Post policy的JSON中需要進行轉義的字符。
轉義字符 | 描述 |
\/ | 斜杠 |
\\ | 反斜杠 |
\” | 雙引號 |
\$ | 美元符 |
\b | 空格 |
\f | 換頁 |
\n | 換行 |
\r | 回車 |
\t | 水平制表符 |
\uxxxx | Unicode字符 |
簽名計算過程
創建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=