除了使用Authorization Header,您还可以在URL中加入签名信息,以便将该URL转给第三方实现授权访问。
注意事项
- 使用在URL中签名的方式,会将授权的数据在过期时间内曝露在互联网上,请预先评估使用风险。
- OSS不支持同时在URL和Header中包含签名。
- PUT和GET请求都支持在URL中签名。
- 您可以为PUT操作生成一个预签名的URL,该URL检查用户是否上传了正确的内容。SDK对请求进行预签名时,将计算请求正文的校验和,并生成包含在预签名URL中的MD5校验和。用户必须上传与SDK生成的MD5校验和相同的内容,否则操作失败。如果要验证MD5,只需在请求中增加Content-MD5头即可。
签名实现
- 签名示例
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2pc56s936****&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv****
如果需要使用STS用户构造URL签名,则必须携带security-token
。https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2pc56s936****&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv****&security-token=CAISowJ1q6Ft5B2yfSjIr5bgIOz31blR9oWmWBfCs3kDR/xm3Imc1zz2IHxMdHJsCeAcs/Q0lGFR5/sflqJIRoReREvCUcZr8szfWcsZos2T1fau5Jko1be0ewHKeQKZsebWZ+LmNpy/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/kFC9MMRVuAcCZhDtVbLRcYgq18D3bKMuu3ORPHm3fZCFES2jBxkmRi86+ysIP+phPVlw/90fRH5dazcJW0Zsx0OJo6Wcq+3+FqM6DQlTNM6hwNtoUO1fYUommb54nDXwQIvUjfbtC5qIM/cFVLAYEhALNBofTGkvl1h/fejYyfyWwWYbkFCHiPFNr9kJCUSbr4a4sjF6zyPnPWycyCLYXleLzhxPWd/2kagAGaXG69BqwYNvrKKI3W8weP3bNc1wQDMXQfiHpFCRG6lYhh3iXFtpwH90A3sTlxzRGvi8+9p63JwrluOHWs+Fj6S6s0cOhKvKRWYE8UuWeXIvv4l6DAGwHDE8BLjLC11f5prUJgI2wb+3hwuBod32Jx+us/1p996Glao725orcb****
您可以在签名URL中添加想要授权的IP地址、IP地址段或VPC ID,避免未授权的终端访问OSS资源。
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?&OSSAccessKeyId=44CF9590006BF252F707&Expires=1475462111&Signature=OjxkTUbT6rXCZcW8QhvlrXQr8vsP80EFdo6oG5qsBx****&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超时时间的具体操作,请参见分享文件。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
等在Header中包含签名中定义的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地址段。如果在生成签名时添加了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())
- 示例二(包含可选参数)
- 签名时,需按照字典序升序排列可选的签名参数。如果参数未配置则为空。
- 当您需要指定具体IP地址访问时,只需在生成签名时添加IP地址(例如
x-oss-ac-source-ip=127.0.0.1
),并在query参数中提供子网掩码用于计算签名(例如x-oss-ac-subnet-mask=32
)。
import base64 import hmac import hashlib import urllib h = hmac.new(accesskey, "GET\n\n\n1141889120\n%2Fexamplebucket%2Foss-api.pdf?\ &x-oss-ac-forward-allow=true\ &x-oss-ac-source-ip=127.0.0.1\ &x-oss-ac-subnet-mask=32\ &x-oss-signature-version=OSS2", hashlib.sha256) Signature = base64.encodestring(h.digest()).strip()
- 示例一(只涉及必选参数)
SDK示例
下表提供各语言SDK生成签名URL的方法以及通过签名URL上传或下载文件的示例。
SDK | URL签名方法 | GitHub示例 | 签名URL使用示例 |
---|---|---|---|
Java SDK | OSSClient.generatePresignedUrl | AuthorizedAccessSample.java | Java |
Python SDK | Bucket.sign_url | sts.py | Python |
PHP SDK | OssClient.signUrl | Signature.php | PHP |
Node.js SDK | Url | signatureUrl.js | Node.js |
Browser.js SDK | Url | signatureUrl.js | Browser.js |
Android SDK | OSSClient.presignConstrainedObjectURL | OSSClient.java | Android |
iOS SDK | presignConstrainURLWithBucketName:withObjectKey:httpMethod:withExpirationInterval:withParameters | OSSClient.h | iOS |
Go SDK | signURL | sign_url.go | Go |
C SDK | oss_gen_signed_url | oss_object.c | C |
C++ SDK | OssClient::GeneratePresignedUrl | OssClient.cc | C++ |
.Net SDK | OssClient.GeneratePresignedUri | UrlSignatureSample.cs | .NET |
错误码
错误码 | 返回消息 | 描述 |
---|---|---|
AccessDenied | 403 Forbidden | 在URL中添加签名时,Signature、Expires和OSSAccessKeyId顺序可以调换,但缺少Signature、Expires或OSSAccessKeyId中的一个或者多个。 |
AccessDenied | 403 Forbidden | 访问的当前时间晚于请求中设定的Expires时间或时间格式错误。 |
InvalidArgument | 400 Bad Request | URL中包含Signature、Expires、OSSAccessKeyId中的一个或者多个,并且Header中也包含签名消息。 |