You need to enable JavaScript to run this app.
导航

携带查询参数 X-Tos-Policy 的 URL 预签名

最近更新时间2023.11.21 10:22:22

首次发布时间2023.03.15 10:52:31

预签名的 URL 仅能生成单个对象的访问链接,如果您想通过预签名 URL 生成桶下目录的访问链接,完成目录的列举,以及目录中对象的查询和下载功能,可以通过携带查询参数 X-Tos-Policy 的 URL 预签名方式实现。通过本文介绍的预签名 URL,您可以在有效期内授予一批对象的访问权限,而不需要对桶或对象本身做任何配置。

列举场景的预签名 URL 格式

https://bucketname.tos-cn-beijing.volces.com/
?X-Tos-Algorithm=TOS4-HMAC-SHA256
&X-Tos-Credential=<access-key-id>/<YYYYMMDD>/<region>/tos/request
&X-Tos-Date=20220101T000000Z
&X-Tos-Expires=86400
&X-Tos-Policy=<policy>
&X-Tos-Signature=<signature>
&X-Tos-Security-Token=<security-token>

参数说明

参数

描述

是否必选

X-Tos-Algorithm

用于标记签名的版本及算法,当前只支持 TOS4-HMAC-SHA256。

X-Tos-Credential

提供 AccessKey ID、日期,区域和服务信息。 格式为 <acces-key-id>/<date>/<region>/tos/request,date 格式为 yyyyMMdd。

X-Tos-Date

当前请求时间(UTC 时间),格式为 yyyyMMddTHHmmssZ。

X-Tos-Expires

该 URL 的有效期,单位为秒。该值为整数,最小为 1,最大为 604800(7 天),即签名有效期最长为 7 天。

X-Tos-Policy

预签名的 URL 对桶中对象的访问策略,值为 Policy,需要经过 Base64 编码。

X-Tos-Signature

计算的签名。

X-Tos-Security-Token

使用临时 AK/SK 鉴权时,必须加上该头域,值为 SecurityToken。

Policy

查询参数 X-Tos-Policy 的值 Policy 为一段经过 UTF-8 和 Base64 编码的 JSON 文本,声明了使用该 URL 请求必须满足的条件,用于验证请求的合法性。
Policy 示例如下:

{
  "conditions": [
    {"bucket": "examplebucket"}, // 等价于 ["eq", "$bucket", "examplebucket"]
    ["starts-with", "$key", "example"]
  ]
}

Policy 中支持的 Conditions 项请参见下表。

参数

参数类型

说明

限制

bucket

string

指定可接受的桶的名称。
支持的匹配类型:精确匹配

必须有且仅能有一个。

key

string

对象名或者对象名的前缀。
支持的匹配类型:精确匹配、Starts With

至少有一个,可以有多个。

Conditions 匹配方式

匹配方式

说明

精确匹配

桶名或对象名必须精确匹配 Conditions 中声明的值。
例如指定 key 值必须为 a,则可以设置为:{"key": "a"} ,等效于:["eq", "$key", "a"]。

Starts With

对象名必须以指定的值开头。以下示例表明对象名必须以 user/user1 开头:
["starts-with", "$key", "user/user1/"]

匹配任何内容

不对对象名做限制,请使用 starts-with 空值 ("")。以下示例表明不对 key 做校验:
["starts-with", "$key", ""]

注意当存在多个 key 的规则时,多个规则间是或的关系,任意一个规则匹配成功,则通过该次请求的合法性校验。

签名计算

本文介绍携带查询参数 X-Tos-Policy 的 URL 预签名方式与 Header 签名的区别。除了构造规范化请求(CanonicalRequest)上的差异外,其余流程均相同,差异点如下:

  • CanonicalRequest 的结构体中中仅包含 CanonicalQueryString 和 HashedPayload。
  • CanonicalQueryString 中仅包含 X-Tos-Algorithm、X-Tos-Credential、X-Tos-Date、X-Tos-Expires、X-Tos-Policy、X-Tos-Security-Token。
  • 使用临时 AK/SK 鉴权时,必须带上 X-Tos-Security-Token 参数。
  • 由于请求的内容未知,需要使用 UNSIGNED-PAYLOAD 代替 HashedPayload。

预签名签名过程示例

针对桶 examplebucket,如果您想要分享对象名前缀(即对应目录概念)为 abc/aaa/abc/ 的所有对象,同时分享对象名为 exampleobject 和 exampleobject1 的两个具体对象,可以构建如下 Policy。

{
  "conditions": [
    {"bucket": "examplebucket"}, // 等价于 ["eq", "$bucket", "examplebucket"]
    ["starts-with", "$key", "abc/"]
    ["starts-with", "$key", "aaa/abc/"]
    ["eq", "$key", "exampleobject"]
    ["eq", "$key", "exampleobject1"]
  ]
}

计算签名的相关信息如下。

参数

区域

cn-beijing

当前请求时间

Sat, 1 Jan 2022 00:00:00 GMT

AccessKeyId

testAK

SecretAccessKey

testSK

预签名有效期

86400 秒

Policy

以下是 Policy 的 JSON 文本 Base64 编码后进行 URL 编码的内容。

eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJleGFtcGxlYnVja2V0In0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYmMvIl0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYWEvYWJjLyJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdCJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdDEi****

CanonicalRequest

X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=testAK%2F20220101%2Fcn-beijing%2Ftos%2Frequest&X-Tos-Date=20220101T000000Z&X-Tos-Expires=86400&X-Tos-Policy=eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJleGFtcGxlYnVja2V0In0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYmMvIl0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYWEvYWJjLyJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdCJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdDEi****
UNSIGNED-PAYLOAD

StringToSign

TOS4-HMAC-SHA256
20220101T000000Z
20220101/cn-beijing/tos/request
07f73a178c9313fb228dbac92bef3293cabcb546809e4ae8eefb16c401ba8d60

SigningKey

HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("testSK", "20220101"), "cn-beijing"), "tos"), "request")

Signture

b9a2a01cdaff37247fcdab58717ab20a35b338138a992b1ba0f04df9dd807ba7

生成请求 URL

URL 生成方式

将上述签名计算得到 Signature,与 CanonicalQueryString 进行拼接可以得到用于生成 ListObjects、ListObjectVersions、HeadObject、GetObject 四种方法的签名 query 参数。其他用户可以基于该签名 query 参数,自主生成相应 URL。签名 query 参数,如下所示。

X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=testAK%2F20220101%2Fcn-beijing%2Ftos%2Frequest&X-Tos-Date=20220101T000000Z&X-Tos-Expires=86400&X-Tos-Policy=eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJleGFtcGxlYnVja2V0In0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYmMvIl0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYWEvYWJjLyJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdCJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdDEiXV19&X-Tos-Signature=b9a2a01cdaff37247fcdab58717ab20a35b338138a992b1ba0f04df9dd80****

BucketName、EndPoint、Path、签名 query 参数及额外 query 参数按照如下方式进行进行拼接,即可生成请求所需的 URL。其中列举对象场景中 ObjectKey 为空;查询和获取对象场景中,ObjectKey 为对象名,额外 query 参数与方法的具体行为有关,在下一节中说明。

https://{BucketName}.{Endpoint}/{ObjectKey}?{签名query参数}&{额外query参数}

注意

在生成 URL 阶段,query 参数间的顺序没有严格要求,本文中签名 query 参数在前,额外 query 参数在后的顺序仅作说明使用。

具体生成示例

本文示例说明如下:

  • examplebucket 为 policy 中对应的桶名。
  • tos-cn-beijing.volces.com 为 Endpoint,与签名计算中的 cn-beijing 地域对应。

列举对象场景

如果其他用户想基于该签名 query 参数,列举分享出来的对象中,前缀为 abc 的所有对象,可以通过携带 query 查询参数 prefix=abc,生成如下具体的 URL,然后通过 Get 请求访问该 URL,实现列举对象。

https://examplebucket.tos-cn-beijing.volces.com/?X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=testAK%2F20220101%2Fcn-beijing%2Ftos%2Frequest&X-Tos-Date=20220101T000000Z&X-Tos-Expires=86400&X-Tos-Policy=eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJleGFtcGxlYnVja2V0In0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYmMvIl0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYWEvYWJjLyJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdCJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdDEiXV19&X-Tos-Signature=b9a2a01cdaff37247fcdab58717ab20a35b338138a992b1ba0f04df9dd807ba7&prefix=abc

额外 query 参数
额外 query 参数可以控制该次请求的某些具体行为。例如,携带 query 参数 prefix=abc/abc/ 可以列举前缀为 abc/abc/ 的对象,携带 query 参数 versions 可以列举多版本对象,更多参数选择请参见 listObjectslistObjectVersions 中的请求参数和消息头部分。

查询/获取对象场景

查询对象和获取对象的 URL 是一致的,区别在于通过 Head 请求访问该 URL,即可实现查询对象,通过 Get 请求访问该 URL,即可实现获取对象。
针对桶 examplebucket 中 exampleobject 对象的 123 版本的多版本对象,查询元数据/获取对象:

https://examplebucket.tos-cn-beijing.volces.com/exampleobject?X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=testAK%2F20220101%2Fcn-beijing%2Ftos%2Frequest&X-Tos-Date=20220101T000000Z&X-Tos-Expires=86400&X-Tos-Policy=eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJleGFtcGxlYnVja2V0In0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYmMvIl0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJhYWEvYWJjLyJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdCJdLFsiZXEiLCIka2V5IiwiZXhhbXBsZW9iamVjdDEiXV19&X-Tos-Signature=b9a2a01cdaff37247fcdab58717ab20a35b338138a992b1ba0f04df9dd807ba7&versionId=123

其中 examplebucket 为 policy 中对应的桶名,exampleobject 为查询/获取对象的对象名。
额外 query 参数:
控制该次请求的具体行为,参数选择请参见 headObjectgetObject 中的请求参数和消息头部分。

注意

headObject 和 getObject 可以在 Header 位置携带消息头控制请求行为,如果有相关需要,在请求 URL 时携带对应消息头即可。