Authentication of Signature Carried in the Table Uploaded Through a Browser

OBS supports browser-based uploads using POST requests. Authenticating such a request uses the signature carried in the form. First, create a policy to specify the requirements for requests, such as bucket name or object name prefix. Then, create a signature based on this policy. The request form to be signed must contain a valid signature and policy. Finally, create a form to upload the object to the bucket.

The process of calculating a signature is as follows:

  1. Encode the policy content in UTF-8.

  2. Encode the result of 1 in Base64.

  3. Use the SK to calculate the HMAC-SHA1 signature on the result of 2.

  4. Encode the result of 3 in Base64 to obtain the signature.

StringToSign = Base64( UTF-8-Encoding-Of( policy ) )
Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, StringToSign ) )

The content of the policy is as follows:

{ "expiration": "2017-12-31T12:00:00.000Z",
  "conditions": [
    {"x-obs-acl": "public-read" },
    {"x-obs-security-token": "YwkaRTbdY8g7q...." },
    {"bucket": "book" },
    ["starts-with", "$key", "user/"]
  ]
}

The policy contains the validity period (see Expiration) and conditions (see Conditions).

Expiration

The expiration field describes when the signature will expire, which is expressed in the format according to ISO 8601 UTC. For example, expiration: 2017-12-31T12:00:00.000Z in the example means that the request becomes invalid after 12:00:00 on December 31, 2017. This field must be specified in a policy. It can only be in the yyyy-MM-dd'T'HH:mm:ss'Z' or yyyy-MM-dd'T'HH:mm:ss.SSS'Z' format.

Conditions

A mechanism used to verify the validity of a request. Conditions are used to define the content that must be contained in a request. In the example, the requested bucket name is book, the object name is prefixed with user/, and the ACL of the object is public read. All items in the form must be included in the policy, excluding AccessKeyId, Signature, file, policy, token, field names, and items with the prefix x-ignore-. The following table lists the items that should be contained in conditions:

Table 1 Conditions contained in a policy

Element

Description

x-obs-acl

ACL in the request.

Supports exact match and conditional match such as starts-with.

content-length-range

Maximum and minimum length of an object to be uploaded. The value can be a range.

Cache-Control, Content-Type, Content-Disposition, Content-Encoding, Expires

Headers specially for REST requests

Supports exact match and conditional match such as starts-with.

key

Name of an object to be uploaded.

Supports exact match and conditional match such as starts-with.

bucket

Name of the requested bucket.

Supports exact match.

success_action_redirect

Redirection address after the upload is successful. For details, see Uploading an Object - POST.

Supports exact match and conditional match such as starts-with.

success_action_status

If success_action_redirect is not specified, the status code is returned to the client when the upload is successful. For details, see Uploading an Object - POST.

Supports exact match.

x-obs-meta-*

User-defined metadata.

Keywords in this element cannot include non-ASCII or unrecognizable characters. If such characters are necessary, they must be encoded and decoded on the client side in either URL or Base64. The server does not perform decoding.

Supports exact match and conditional match such as starts-with.

x-obs-*

Other header fields with prefix x-obs-.

Supports exact match and conditional match such as starts-with.

x-obs-security-token

Field name in the request header.

Mandatory field for the temporary AK/SK and security token authentication.

The table below describes the supported condition matching types:

Table 2 Policy condition matching methods

Matching Method

Description

Exact Matches

The default type. The form field value must match the value specified in conditions. This example indicates the object ACL must be set to public-read:

{"x-obs-acl": "public-read"} or ["eq", "$x-obs-acl", "public-read"], which are equivalent.

Starts With

The form field value must start with the specified value. This example indicates the object key must start with user/:

["starts-with", "$key", "user/"]

Matching Any Content

To allow any content within a form field, use "starts-with" with an empty value (""). This example allows any value for success_action_redirect:

["starts-with", "$success_action_redirect", ""]

Specifying Ranges

Only used to restrict the size of the uploaded file. Quotation marks are not allowed for element values. This example allows a file size from 1 to 10 MB, that is, from 1048576 to 10485760:

["content-length-range", 1048576, 10485760]

Note

Policies use the JSON format. Use curly brackets ({}) or square brackets ([]) to specify conditions. Curly brackets ({}) can enclose a key and a value separated by a colon (:). Square brackets ([]) can contain a condition type, key, and value separated by commas (,). Use the dollar sign ($) ahead of a key to mark a variable.

The table below lists the characters that must be escaped in a policy.

Table 3 Characters that must be escaped in a policy

Character After Escape

Real Character

\\

Backslash (\)

\$

Dollar symbol ($)

\b

Backspace

\f

Page up and down

\n

Newline characters

\r

Enter

\t

Horizontal tab

\v

Vertical tab

\uxxxx

All Unicode characters

Request and Policy Examples

The following tables provide some example requests and policies.

Example 1: Upload the testfile.txt object to bucket examplebucket and set the object ACL to public-read.

Request

Policy

POST / HTTP/1.1

Host: examplebucket.obs.region.example.com

Content-Type: multipart/form-data; boundary=7e32233530b26

Content-Length: 1250

--7e32233530b26

Content-Disposition: form-data; name="key"

testfile.txt

--7e32233530b26

Content-Disposition: form-data; name="x-obs-acl"

public-read

--7e32233530b26

Content-Disposition: form-data; name="content-type"

text/plain

--7e32233530b26

Content-Disposition: form-data; name="AccessKeyId"

UDSIAMSTUBTEST000002

--7e32233530b26

Content-Disposition: form-data; name="policy"

ewogICJleHBpcmF0aW9uIjogIjIwMTktMDctMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0IiB9LAogICAgWyJlcSIsICIka2V5IiwgInRlc3RmaWxlLnR4dCJdLAoJeyJ4LW9icy1hY2wiOiAicHVibGljLXJlYWQiIH0sCiAgICBbImVxIiwgIiRDb250ZW50LVR5cGUiLCAidGV4dC9wbGFpbiJdLAogICAgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDYsIDEwXQogIF0KfQo=

--7e32233530b26

Content-Disposition: form-data; name="Signature"

xxl7bZs/5FgtBUggOdQ88DPZUo0=

--7e32233530b26

Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt"

Content-Type: text/plain

123456

--7e32233530b26

Content-Disposition: form-data; name="submit"

Upload

--7e32233530b26--

{

"expiration": "2019-07-01T12:00:00.000Z",

"conditions": [

{"bucket": "examplebucket" },

["eq", "$key", "testfile.txt"],

{"x-obs-acl": "public-read" },

["eq", "$Content-Type", "text/plain"]

]

}

Example 2: Upload the file/obj1 object to bucket examplebucket and configure the four custom metadata items of the object.

Request

Policy

POST / HTTP/1.1

Host: examplebucket.obs.region.example.com

Content-Type: multipart/form-data; boundary=7e329d630b26

Content-Length: 1597

--7e3542930b26

Content-Disposition: form-data; name="key"

file/obj1

--7e3542930b26

Content-Disposition: form-data; name="AccessKeyId"

UDSIAMSTUBTEST000002

--7e3542930b26

Content-Disposition: form-data; name="policy"

ewogICJleHBpcmF0aW9uIjogIjIwMTktMDctMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0IiB9LAogICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgImZpbGUvIl0sCiAgICB7Ingtb2JzLW1ldGEtdGVzdDEiOiJ2YWx1ZTEifSwKICAgIFsiZXEiLCAiJHgtb2JzLW1ldGEtdGVzdDIiLCAidmFsdWUyIl0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiR4LW9icy1tZXRhLXRlc3QzIiwgImRvYyJdLAogICAgWyJzdGFydHMtd2l0aCIsICIkeC1vYnMtbWV0YS10ZXN0NCIsICIiXQogIF0KfQo=

--7e3542930b26

Content-Disposition: form-data; name="signature"

HTId8hcaisn6FfdWKqSJP9RN4Oo=

--7e3542930b26

Content-Disposition: form-data; name="x-obs-meta-test1"

value1

--7e3542930b26

Content-Disposition: form-data; name="x-obs-meta-test2"

value2

--7e3542930b26

Content-Disposition: form-data; name="x-obs-meta-test3"

doc123

--7e3542930b26

Content-Disposition: form-data; name="x-obs-meta-test4"

my

--7e3542930b26

Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt"

Content-Type: text/plain

123456

--7e3542930b26

Content-Disposition: form-data; name="submit"

Upload

--7e3542930b26--

{

"expiration": "2019-07-01T12:00:00.000Z",

"conditions": [

{"bucket": "examplebucket" },

["starts-with", "$key", "file/"],

{"x-obs-meta-test1":"value1"},

["eq", "$x-obs-meta-test2", "value2"],

["starts-with", "$x-obs-meta-test3", "doc"],

["starts-with", "$x-obs-meta-test4", ""]

]

}