All Products
Search
Document Center

Object Storage Service:Example of uploading signature headers in OSS using Python

Last Updated:Mar 20, 2026

This example shows how to manually construct an Authorization header and upload an object to OSS using the PutObject API in Python 2.7, without relying on the OSS SDK's built-in signing.

Note

For production use, use the OSS SDK, which handles request signing automatically. Use this example only when you cannot use the SDK — for example, when integrating OSS into a custom HTTP stack or debugging authentication flows.

Prerequisites

Before you begin, ensure that you have:

  • An Alibaba Cloud account with an AccessKey ID and AccessKey secret

  • An OSS bucket in the oss-cn-hangzhou region (or update the endpoint to match your bucket's region)

  • A local file to upload

  • Python 2.7 with the standard library available (hmac, base64, urllib2)

How it works

A signed PutObject request requires three headers:

HeaderDescription
AuthorizationAuthenticates the request. Format: OSS <AccessKeyID>:<Base64(HMAC-SHA1(StringToSign))>
Content-TypeThe MIME type of the object being uploaded (for example, image/png)
DateThe current UTC time in GMT format, matching the time used when computing the signature

Authorization header format

The Authorization header has this structure:

OSS <AccessKeyID>:<Signature>
ComponentDescription
OSSFixed prefix that identifies the Alibaba Cloud OSS signing scheme
<AccessKeyID>Your AccessKey ID
:Delimiter between the AccessKey ID and the signature
<Signature>A Base64-encoded HMAC-SHA1 hash of the string-to-sign

String-to-sign format

The string-to-sign is constructed as:

PUT\n
\n
<Content-Type>\n
<Date>\n
/<bucket>/<object>

Where each \n is a literal newline character.

Upload an object with a signed request

The following Python 2.7 code constructs the signature and uploads an object using the PutObject API.

Replace the placeholder values before running:

PlaceholderDescriptionExample
Your accesskeyYour AccessKey IDLTAI5tXxxx
Your AccesskeySecretYour AccessKey secretxXxXxXx
Your bucket nameThe name of your OSS bucketexamplebucket
/Users/wanghe/Documents/20190717101549.pngThe local path of the file to upload/path/to/your/file.png
# -*- coding: utf-8 -*-
import base64
import hmac
import sha
import urllib2
from datetime import datetime


accesskey='Your accesskey';
accesskeysecret='Your AccesskeySecret
endpoint='oss-cn-hangzhou.aliyuncs.com'
bucket='Your bucket name'
# The path of the object you want to upload.
object='mytest/test.png'
GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'


time = datetime.utcnow().strftime(GMT_FORMAT)
print(time)
signature = hmac.new(accesskeysecret,
"PUT\n\nimage/png\n"+time+"\n"+"/"+bucket+"/"+object,sha)
Signature = base64.b64encode(signature.digest())
print("Signature: %s" % Signature)
opener = urllib2.build_opener(urllib2.HTTPHandler)
with open("/Users/wanghe/Documents/20190717101549.png") as f:
data=f.read()
request = urllib2.Request("http://"+bucket+"."+endpoint+"/"+object, data=data)
request.add_header("Authorization", "OSS "+accesskey+":"+Signature)
request.add_header("Content-Type", "image/png")
request.add_header("Date", time)
request.get_method = lambda:"PUT"
url = opener.open(request)

Troubleshooting

If the signature is incorrect, OSS returns a 403 SignatureDoesNotMatch error. Common causes include:

  • The Date value used to compute the signature does not match the Date header sent in the request

  • The string-to-sign does not use literal newline characters between each field

  • The Content-Type value in the string-to-sign does not match the Content-Type header in the request

What's next