除了通过 HTTP 请求头部的 Authorization 字段进行签名授权外,您还可以生成一个包含签名和其他必要的请求信息的预签名 URL。通过这种方式,您可以在不透露访问凭证的情况下,授予第三方在特定有效期内对 OSS 资源的访问权限。本文介绍如何使用 V1 签名算法实现在 URL 中包含签名。
OSS 支持更安全的 V4 签名算法,建议您使用 V4 签名。更多信息,请参见 V4 签名 。
SDK 签名实现
OSS SDK 已自动实现 V1 签名,您使用 OSS SDK 时无需关注签名问题。如果您想了解具体语言的签名实现,请参考 OSS SDK 的代码。OSS SDK 签名实现的文件请参见下表。
SDK |
签名实现 |
使用示例 |
Java |
||
PHP |
||
Node.js |
||
Browser.js |
||
Python |
||
Android |
||
iOS |
||
Go |
||
C++ |
||
C |
||
.Net |
||
Ruby |
注意事项
-
使用在 URL 中签名的方式,会将授权的数据在过期时间内暴露在互联网上,请预先评估使用风险。
-
OSS 不支持同时在 URL 和 Header 中包含签名。
-
您可以为 PUT 操作生成一个预签名的 URL,该 URL 用于检查是否上传了正确的内容。SDK 对请求进行预签名时,将计算请求正文的校验和,并生成包含在预签名 URL 中的 MD5 校验和。用户必须上传与 SDK 生成的 MD5 校验和相同的内容,否则操作失败。如果要验证 MD5,只需在请求中增加 Content-MD5 头即可。
签名实现
-
签名示例
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2p***********&Expires=1141889120&Signature=****Pxyb****mGa%****272YEAiv****
如果需要使用 STS 用户构造 URL 签名,则必须携带
security-token
。https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2p***********&Expires=1141889120&Signature=****Pxyb****mGa%****272YEAiv****&security-token=CAIS****q6Ft5B2yfSjIr****Oz31blR9oWmWBf****DR/xm3Imc****IHxMdHJsCeAcs/Q0lGFR5/sflqJIR****EvCUcZr8szfWcsZos2****u5Jko1be0ewHKeQKZsebWZ+LmNpy/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/kFC9MMRVuAcCZhDtVbLRcYgq18D3bKMuu3ORPHm3fZCFES2jBxkmRi86+ysIP+phPVlw/90fRH5dazcJW0Zsx0OJo6Wcq+3+FqM6DQlTNM6hwNtoUO1fYUommb54nDXwQIvUjfbtC5qIM/cFVLAYEhAL****TGkvl1h/fejYyfyW****kFCHiPF****JCUSbr4a4sjF6zyPnPWycyCLYXleLzhxPWd/2kagAGaXG69BqwYNvrKKI3W8****bNc1wQDMXQfiHpFCRG6lYhh3****pwH90A3sTlxzRGvi8+****JwrluOHWs+Fj6S6s0cOhKvKRWYE8UuWeXIvv4l6DAGwH****LjLC11f5prUJ****b+3hwuBod32Jx+us/1p996Glao725orcb****
您可以在签名 URL 中添加想要授权的 IP 地址、IP 地址段或 VPC ID,避免未授权的终端访问 OSS 资源。
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?&OSSAccessKeyId=44CF****************&Expires=1475462111&Signature=77Dv****************&x-oss-ac-subnet-mask=32
-
参数说明
名称
类型
是否必选
描述
OSSAccessKeyId
字符串
是
指定 URL 签名中使用的 AccessKey ID。
Expires
数字
是
Unix 时间戳(自 UTC 时间 1970 年 01 月 01 号开始的秒数),用于标识该 URL 的超时时间,单位为秒。如果 OSS 接收到该 URL 请求的时间晚于签名中包含的 Expires 参数时,则返回请求超时的错误码。例如,当前时间是 1141889060,开发者希望创建一个 60 秒后自动失效的 URL,则可以设置 Expires 时间为 1141889120。
说明出于安全考虑,OSS 控制台中默认 URL 的有效时间为 3600 秒,最大值为 32400 秒。关于修改 URL 超时时间的具体操作,请参见 使用文件 URL 。
Signature
字符串
是
签名信息。格式如下:
Signature = urlencode(base64(hmac-sha1(AccessKeySecret, VERB + "\n" + CONTENT-MD5 + "\n" + CONTENT-TYPE + "\n" + EXPIRES + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)))
-
所有 OSS 支持的请求和各种 Header 参数,在 URL 中进行签名的算法和在 Header 中包含签名的算法类似。
-
生成 URL 中的签名字符串时,除了将 Date 参数替换为 Expires 参数外,仍然包含
CONTENT-TYPE
、CONTENT-MD5
、CanonicalizedOSSHeaders
等 签名版本 1 中定义的 Header(请求中虽然仍有 Date 请求 Header,但无需将 Date 加入签名字符串中)。 -
在 URL 中包含签名时必须对 URL 进行编码。如果在 URL 中多次传入 Signature、Expires 或 OSSAccessKeyId,则以第一次传入的值为准。
-
使用 URL 签名时,OSS 会先验证请求时间是否晚于 Expires 时间,然后再验证签名。
security-token
字符串
否
安全令牌。只有当使用 STS 用户构造 URL 签名时,才需要设置此参数。
说明关于搭建 STS 服务的具体操作,请参见 使用 STS 临时访问凭证访问 OSS 。您可以通过调用 STS 服务的 AssumeRole 接口或者使用 各语言 STS SDK 来获取临时访问凭证。临时访问凭证包括临时访问密钥(AccessKey ID 和 AccessKey Secret)和安全令牌(SecurityToken)。
x-oss-ac-source-ip
字符串
否
指定 IP 地址或者 IP 地址段。
重要-
该参数只需要在生成 signature 时使用,不需要在 URL 中携带该参数。
-
如果在生成签名时添加了 IP 地址或 IP 地址段,则需要传递参数 x-oss-ac-subnet-mask ,用于标记子网掩码。
x-oss-ac-subnet-mask
数字
否
子网掩码中 1 的个数。如果请求中携带该参数,OSS 会将实际请求 IP 地址与子网掩码进行求与,然后用于计算签名是否正确。如果该参数被恶意篡改,将导致签名无法校验通过。
x-oss-ac-vpc-id
字符串
否
指定 VPC ID。指定该参数后,OSS 会判断是否为对应 VPC ID 来源的请求。如果请求是从该 VPC ID 发起且该参数已赋值,则同时校验 VPC ID 和来源 IP 地址或 IP 地址段。
x-oss-ac-forward-allow
布尔型
否
指定是否允许转发请求。OSS 如果检测到该字段并且请求中带有
X-Forwarded-For
(可能为多个 IP 地址),则将X-Forwarded-For
的值用于计算签名校验。取值如下:
-
true:表示允许转发请求。
重要设置为 true 存在请求头被篡改劫持的风险。
-
false(默认值):不允许转发请求。
-
-
生成签名的 Python 示例代码(只涉及必选参数)
import base64 import hmac import hashlib import urllib h = hmac.new("accesskey", "GET\n\n\n1141889120\n/examplebucket/oss-api.pdf", hashlib.sha1) urllib.quote(base64.encodestring(h.digest()).strip())
错误码
错误码 |
返回消息 |
描述 |
AccessDenied |
403 Forbidden |
在 URL 中添加签名时,Signature、Expires 和 OSSAccessKeyId 顺序可以调换,但不能缺少 Signature、Expires 或 OSSAccessKeyId 中的一个或者多个。 |
AccessDenied |
403 Forbidden |
访问的当前时间晚于请求中设定的 Expires 时间或时间格式错误。 |
InvalidArgument |
400 Bad Request |
URL 中包含 Signature、Expires、OSSAccessKeyId 中的一个或者多个,并且 Header 中也包含签名消息。 |