POST V1 signature

Updated at:

POST V1 signing secures the upload requests that clients send to Object Storage Service (OSS) through the PostObject operation. The application server calculates a signature from an upload policy and delivers both to the client, which submits them as form fields. OSS verifies the signature of each POST request and rejects requests whose signature is invalid.

Note

OSS supports the more secure V4 signature algorithm. (Recommended) Use V4 signing. For more information, see V4 signature.

When a POST V1 signature is required

HTTP POST requests to OSS support the V1 signature algorithm, which this topic refers to as POST V1 signing. Before you calculate a POST V1 signature, review the following conditions and dependencies:

  • Bucket ACL — A PostObject request must carry a signature when the ACL of the destination bucket is public-read or private.

  • Form fields — Provide the OSSAccessKeyId, Signature, and policy form fields as a group. If any one of the three fields is present in the form, the other two are also required. For field-level descriptions, see Form fields.

  • Where the signature is calculated — The application server calculates the signature and delivers it, together with the upload policy, to the client. The client uses this information to construct the PostObject request.

  • Credentials — The signature is calculated from the AccessKey secret. The OSSAccessKeyId form field carries the AccessKey ID of the same AccessKey pair.

Calculate a POST V1 signature

Calculate a POST V1 signature on your application server in the following three steps:

  1. Create the policy. Create a UTF-8 encoded policy. For the policy syntax and the conditions that you can declare, see Policy structure.

  2. Construct the string to sign (StringToSign). Base64-encode the policy. The resulting string is the string to be signed (StringToSign).

  3. Calculate the signature. Use the AccessKey secret to sign the string to be signed. The signing formula is Signature = base64(hmac-sha1(AccessKeySecret,base64(policy))).

The following figure shows the POST V1 signature calculation process.

image

Example: calculate a POST V1 signature in Java

The following Java example runs the three steps of POST V1 signing against the example policy described in Policy structure. Step 3 calls the OSS Java SDK, which applies the base64(hmac-sha1(AccessKeySecret,base64(policy))) formula to the string to be signed.

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

public class Demo {
    public static void main(String[] args) {
        // Before running this code example, make sure the OSS_ACCESS_KEY_SECRET environment variable is set.
        String accessKeySecret =  System.getenv().get("OSS_ACCESS_KEY_SECRET");

        // Step 1: Create the 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/jpeg\", \"image/png\"]],\n" +
                "    [\"not-in\", \"$cache-control\", [\"no-cache\"]]\n" +
                "  ]\n" +
                "}";

        // Step 2: Construct the string to sign (StringToSign).
        String stringToSign = new String(Base64.encodeBase64(policy.getBytes()));

        // Step 3: Calculate the signature.
        String signature = com.aliyun.oss.common.auth.ServiceSignature.create().computeSignature(accessKeySecret, stringToSign);
        System.out.println("signature:" + signature);
    }
}

The signature is printed in the following format. The printed value is a Base64-encoded string that depends on your AccessKey secret and on the exact bytes of your policy, so your output differs from the following sample.

signature:****

Submit the calculated value in the Signature form field of the PostObject request, together with the OSSAccessKeyId and policy form fields.

Form fields

The following form elements are specific to POST V1 signing. For other common form elements, see PostObject form elements. For the conditions under which these fields are required, see When a POST V1 signature is required.

FieldTypeDescription
OSSAccessKeyIdStringThe AccessKey ID in the AccessKey pair. Default value: None.
SignatureStringThe signature calculated from the AccessKey secret and the policy. OSS uses the signature to verify the validity of the POST request. The key of this form field is case-insensitive, but the value is case-sensitive. Default value: None. For how OSS verifies the signature of a POST request, see PostObject.
policyStringThe security policy that declares the permissions and constraints of the upload. The policy is defined in JSON format and must include the expiration and conditions fields. For details, see Policy structure.

Policy structure

The policy form field is a security policy that defines the permissions and constraints for uploading objects to OSS through an HTML form. The policy is defined in JSON format and restricts upload operations through multiple parameters, such as the allowed bucket name, object prefix, expiration time, allowed HTTP methods, content size limits, and content type restrictions.

The policy must include the expiration and conditions fields, as shown in the following example.

{
  "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/jpeg", "image/png"]],
    ["not-in", "$cache-control", ["no-cache"]]
  ]
}

The policy contains the following elements:

  • expiration — Specifies the expiration time of the policy in ISO 8601 GMT format. For example, 2023-12-03T13:00:00.000Z means the POST request must be initiated before 13:00 GMT on December 3, 2023.

  • conditions — Specifies the valid values for the form fields in the POST request.

The following table describes the fields that you can declare in conditions.

FieldTypeRequiredDescriptionCondition matching modes
bucketStringNoThe bucket name.bucket
content-length-rangeStringNoThe minimum and maximum allowed sizes of the object to upload, in bytes.content-length-range
success_action_statusStringNoThe HTTP status code returned after a successful upload.eq, eq-ci, starts-with, starts-with-ci, in, in-ci, not-in, not-in-ci
keyStringNoThe name of the object to upload.eq, eq-ci, starts-with, starts-with-ci, in, in-ci, not-in, not-in-ci
content-typeStringNoRestricts the content type of the object to upload.eq, eq-ci, starts-with, starts-with-ci, in, in-ci, not-in, not-in-ci
cache-controlStringNoSpecifies the caching behavior of the object.eq, eq-ci, starts-with, starts-with-ci, in, in-ci, not-in, not-in-ci

Condition matching modes

The following table describes the condition matching modes that you can use in the conditions field of a POST V1 policy.

Condition matching modeDescription
content-length-rangeSpecifies the allowed minimum and maximum object sizes for uploads. For example, to allow object sizes from 1 to 10 bytes, write ["content-length-range", 1, 10].
eqPerforms an exact match. The value of the form field must exactly match the value declared in the conditions. For example, to require the value of the key form field to be a, write ["eq", "$key", "a"].
starts-withPerforms a prefix match. The value of the form field must start with the specified prefix. For example, to require the value of the key form field to start with user/user1, write ["starts-with", "$key", "user/user1"].
inChecks whether the value is included in a specified list of strings. For example, when you upload an image through the PostObject operation and want to allow multiple image formats, use ["in", "$content-type", ["image/jpeg", "image/png"]].
not-inChecks whether the value is excluded from a specified list of strings. For example, when you upload an object through the PostObject operation and want to disallow the no-cache value for the cache behavior, use ["not-in", "$cache-control", ["no-cache"]].
eq-ciPerforms a case-insensitive exact match. The value of the form field must match the value declared in the conditions. The comparison is performed in lowercase. For example, for ["eq-ci", "$key", "AbC"], object names such as abc, ABC, and aBc all match.
starts-with-ciPerforms a case-insensitive prefix match. The value of the form field must start with the specified prefix. The comparison is performed in lowercase. For example, for ["starts-with-ci", "$key", "User/"], values that start with user/, USER/, or User/ all match.
in-ciPerforms a case-insensitive check to determine whether the value is included in a specified list of strings. The comparison is performed in lowercase. For example, for ["in-ci", "$content-type", ["IMAGE/JPEG", "image/PNG"]], values such as image/jpeg and IMAGE/PNG all match.
not-in-ciPerforms a case-insensitive check to determine whether the value is excluded from a specified list of strings. The comparison is performed in lowercase. For example, for ["not-in-ci", "$cache-control", ["No-Cache"]], values such as no-cache, NO-CACHE, and No-Cache are all excluded.

Policy escape characters

In a POST policy, the dollar sign ($) represents a variable. To include a literal dollar sign, use the escape character \$. The following table describes the characters that must be escaped in the policy JSON.

Escape characterDescription
\/Forward slash
\\Backslash
\"Double quotation mark
\$Dollar sign
\bSpace
\fForm feed
\nLine break
\rCarriage return
\tHorizontal tab
\uxxxxUnicode character