除了使用Authorization Header,您还可以在URL中加入签名信息,以便将该URL转给第三方实现授权访问。

注意事项

  • 使用在URL中签名的方式,会将授权的数据在过期时间内曝露在互联网上,请预先评估使用风险。
  • OSS不支持同时在URLHeader中包含签名。
  • PUTGET请求都支持在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时间19700101号开始的秒数),用于标识该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-TYPECONTENT-MD5CanonicalizedOSSHeadersHeader中包含签名中定义的Header(请求中虽然仍有Date请求Header,但无需将Date加入签名字符串中)。
    • URL中包含签名时必须对URL进行编码。如果在URL中多次传入Signature、ExpiresOSSAccessKeyId,则以第一次传入的值为准。
    • 使用URL签名时,OSS会先验证请求时间是否晚于Expires时间,然后再验证签名。
    security-token字符串安全令牌。只有当使用STS用户构造URL签名时,才需要设置此参数。
    说明 关于搭建STS服务的具体操作,请参见使用STS临时访问凭证访问OSS。您可以通过调用STS服务的AssumeRole接口或者使用各语言STS SDK来获取临时访问凭证。临时访问凭证包括临时访问密钥(AccessKey IDAccessKey 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上传或下载文件的示例。

SDKURL签名方法GitHub示例签名URL使用示例
Java SDKOSSClient.generatePresignedUrlAuthorizedAccessSample.javaJava
Python SDKBucket.sign_urlsts.pyPython
PHP SDKOssClient.signUrlSignature.phpPHP
Node.js SDKUrlsignatureUrl.jsNode.js
Browser.js SDKUrlsignatureUrl.jsBrowser.js
Android SDKOSSClient.presignConstrainedObjectURLOSSClient.javaAndroid
iOS SDKpresignConstrainURLWithBucketName:withObjectKey:httpMethod:withExpirationInterval:withParametersOSSClient.hiOS
Go SDKsignURLsign_url.goGo
C SDKoss_gen_signed_urloss_object.cC
C++ SDKOssClient::GeneratePresignedUrlOssClient.ccC++
.Net SDKOssClient.GeneratePresignedUriUrlSignatureSample.cs.NET

错误码

错误码返回消息描述
AccessDenied403 ForbiddenURL中添加签名时,Signature、ExpiresOSSAccessKeyId顺序可以调换,但缺少Signature、ExpiresOSSAccessKeyId中的一个或者多个。
AccessDenied403 Forbidden访问的当前时间晚于请求中设定的Expires时间或时间格式错误。
InvalidArgument400 Bad RequestURL中包含Signature、Expires、OSSAccessKeyId中的一个或者多个,并且Header中也包含签名消息。