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:
Encode the policy content in UTF-8.
Encode the result of 1 in Base64.
Use the SK to calculate the HMAC-SHA1 signature on the result of 2.
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:
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:
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.
Character After Escape | Real Character |
---|---|
| Backslash (\) |
| Dollar symbol ($) |
| Backspace |
| Page up and down |
| Newline characters |
| Enter |
| Horizontal tab |
| Vertical tab |
| 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", ""] ] } |