对请求进行身份验证:使用查询参数(Amazon 签名版本 4)
如身份验证概述(请参阅身份验证方法)中所述,您可以使用查询字符串参数提供身份验证信息。当您想要在 URL 中完整表达请求时,使用查询参数对请求进行身份验证很有用。此方法也称为对 URL 进行预签名。
预签名 URL 的一个使用案例场景是,您可以授予对 Amazon S3 资源的临时访问权限。例如,您可以在网站上嵌入预签名 URL,或者在命令行客户端(例如 Curl)中使用它来下载对象。
注意
也可以使用 Amazon CLI 来创建预签名 URL。有关更多信息,请参阅《Amazon CLI Command Reference》中的 presign。
以下是示例预签名 URL。
https://examplebucket.s3.amazonaws.com/test.txt ?X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=<your-access-key-id>/20130721/us-east-1/s3/aws4_request &X-Amz-Date=20130721T201207Z &X-Amz-Expires=86400 &X-Amz-SignedHeaders=host &X-Amz-Signature=<signature-value>
在示例 URL 中,注意以下各项:
-
为了便于阅读,添加了换行符。
-
URL 中的
X-Amz-Credential值显示“/”字符只是为了方便阅读。实际上,它应该编码为%2F。例如:&X-Amz-Credential=<your-access-key-id>%2F20130721%2Fus-east-1%2Fs3%2Faws4_request
下表介绍了 URL 中提供身份验证信息的查询参数。
| 查询字符串参数名称 | 示例值 |
|---|---|
X-Amz-Algorithm |
标识 Amazon 签名版本以及用于计算签名的算法。 对于 Amazon 签名版本 4,您可以将此参数值设置为 |
X-Amz-Credential |
除了访问密钥 ID 外,该参数还提供签名有效的范围(Amazon Web Services 区域和服务)。该值必须与您在签名计算中使用的范围匹配(后续部分将对此进行说明)。该参数值的一般形式如下:
例如:
对于 Amazon S3, |
X-Amz-Date |
日期和时间格式必须遵循 ISO 8601 标准,并且必须按照“ |
X-Amz-Expires |
提供生成的预签名 URL 的有效时间段(以秒为单位)。例如, 预签名 URL 的有效期最长为七天,因为您在签名计算中使用的签名密钥的有效期最长为七天。 |
X-Amz-SignedHeaders |
列出用于计算签名的标头。签名计算中需要以下标头:
注意为了提高安全性,您应该签署计划在请求中包含的所有请求标头。 |
X-Amz-Signature |
提供签名以验证您的请求。该签名必须与 Amazon S3 计算出的签名相匹配;否则 Amazon S3 会拒绝该请求。例如, 以下部分将介绍签名计算: |
X-Amz-Security-Token |
如果使用来自 STS 服务的凭证,则为可选凭证参数。 |
计算签名
下图说明了签名计算过程。
下表介绍了图中显示的函数。您需要为这些函数实现代码。
| 函数 | 说明 |
|---|---|
Lowercase() |
将字符串转换为小写。 |
Hex() |
base-16 编码的小写形式。 |
SHA256Hash() |
安全哈希算法(SHA)加密哈希函数。 |
HMAC-SHA256() |
使用 SHA256 算法和提供的签名密钥计算 HMAC。这是最终的签名。 |
Trim() |
删除所有前导空格或尾随空格。 |
UriEncode() |
URI 对每个字节进行编码。UriEncode() 必须强制执行以下规则:
重要由于底层 RFC 中的实现差异和相关歧义,您开发平台提供的标准 UrienCode 函数可能无法正常工作。建议您编写自己的自定义 UrienCode 函数,以确保编码能够正常工作。 以下是 Java 中的 UriEncode() 函数示例。
|
有关签名过程(创建规范请求、待签字符串和签名计算的详细信息)的更多信息,请参阅 Authorization 标头的签名计算:在单个分块中传输有效载荷(Amazon 签名版本 4)。除了在预签名 URL 中创建 CanonicalRequest 之外,过程大致相同,如下所示:
-
您未在规范请求中包含有效载荷哈希值,原因是当您创建预签名 URL 时,您并不知道有效载荷内容,因为该 URL 用于上传任意有效载荷。而应使用常量字符串
UNSIGNED-PAYLOAD。 -
规范查询字符串必须包含上表中除
X-Amz-Signature之外的所有查询参数。 -
对于 S3,如果使用源自 STS 服务的凭证,您必须在 URL 中包含
X-Amz-Security-Token查询参数。 -
规范标头必须包含 HTTP
host标头。如果您计划包含任何x-amz-*标头,则还必须添加这些标头以进行签名计算。您可以选择添加您计划在请求中包含的所有其它标头。为了提高安全性,您应该对尽可能多的标头进行签名。如果您添加的已签名标头也是已签名的查询参数,而它们的值不同,则由于输入存在冲突,您将收到InvalidRequest错误消息。
一个示例
假设您的 examplebucket 存储桶中有一个对象 test.txt。您希望通过创建预签名 URL 与他人共享此对象达 24 小时(86400 秒)。
https://examplebucket.s3.amazonaws.com/test.txt ?X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request &X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host &X-Amz-Signature=<signature-value>
以下步骤首先说明签名计算,然后说明预签名 URL 的构造。该示例作出以下附加假设:
-
请求时间戳为
Fri, 24 May 2013 00:00:00 GMT。 -
存储桶位于美国东部(弗吉尼亚州北部)区域,凭证
Scope和Signing Key计算使用us-east-1作为区域说明符。有关更多信息,请参阅 https://docs.amazonaws.cn/general/latest/gr/rande.html#s3_region 中的Amazon Web Services 一般参考区域和终端节点。
您可以将此示例用作测试用例来验证您的代码计算的签名;但是,您必须使用相同的存储桶名称、对象键、时间戳和以下示例凭证:
| 参数 | 值 |
|---|---|
AWSAccessKeyId |
AKIAIOSFODNN7EXAMPLE |
AWSSecretAccessKey |
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
-
StringToSign
-
CanonicalRequest
GET /test.txt X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host host:examplebucket.s3.amazonaws.com host UNSIGNED-PAYLOAD -
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 3bfa292879f6447bbcda7001decf97f4a54dc650c8942174ae0a9121cf58ad04
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404现在,您已经掌握了构造预签名 URL 的所有信息。此示例生成的 URL 如下所示(您可以使用它来比较您的预签名 URL):
https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404
示例 2
以下是一个显示带有 X-Amz-Security-Token 参数的预签名 URL 的示例(与前一个示例无关)。
https://examplebucket.s3.us-east-1.amazonaws.com/test.txt ?X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request &X-Amz-Date=20200524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host &X-Amz-Security-Token=IQoJb3JpZ2luX2VjEMv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJGMEQCIBSUbVdj9YGs2g0HkHsOHFdkwOozjARSKHL987NhhOC8AiBPepRU1obMvIbGU0T%2BWphFPgK%2Fqpxaf5Snvm5M57XFkCqlAgjz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAAaDDQ3MjM4NTU0NDY2MCIM83pULBe5%2F%2BNm1GZBKvkBVslSaJVgwSef7SsoZCJlfJ56weYl3QCwEGr2F4BmCZZyFpmWEYzWnhNK1AnHMj5nkfKlKBx30XAT5PZGVrmq4Vkn9ewlXQy1Iu3QJRi9Tdod8Ef9%2FyajTaUGh76%2BF5u5a4O115jwultOQiKomVwO318CO4l8lv%2F3HhMOkpdanMXn%2B4PY8lvM8RgnzSu90jOUpGXEOAo%2F6G8OqlMim3%2BZmaQmasn4VYRvESEd7O72QGZ3%2BvDnDVnss0lSYjlv8PP7IujnvhZRnj0WoeOyMe1lL0wTG%2Fa9usH5hE52w%2FYUJccOn0OaZuyROuVsRV4Q70sbWQhUvYUt%2B0tUMKzm8vsFOp4BaNZFqobbjtb36Y92v%2Bx5kY6i0s8QE886jJtUWMP5ldMziClGx3p0mN5dzsYlM3GyiJ%2FO1mWkPQDwg3mtSpOA9oeeuAMPTA7qMqy9RNuTKBDSx9EW27wvPzBum3SJhEfxv48euadKgrIX3Z79ruQFSQOc9LUrDjR%2B4SoWAJqK%2BGX8Q3vPSjsLxhqhEMWd6U4TXcM7ku3gxMbzqfT8NDg%3D &X-Amz-Signature=<signature-value>