简体   繁体   中英

How to create a Shared Access Signature for a container with the Azure Python SDK

I am trying to create a valid Shared Access Signature URL for a container in Azure storage, using the Azure Python SDK. I'm trying to generate it to be effective immediately, to expire after 30 days, and to give read & write access to the whole container (not just the blob). The below code works fine, and it prints the final URL at the end. I also manually verified in the portal that the container and blob were successfully created.

However, after pasting the URL into a browser, I receive the following error message:

 <?xml version="1.0" encoding="UTF-8"?> -<Error> <Code>AuthenticationFailed</Code> <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:adecbe4e-0001-007c-0d19-40670c000000 Time:2015-12-26T20:10:45.9030215Z</Message> <AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail> </Error> 

It seems the issue must be with this line of code:

sasToken = blob_service.generate_shared_access_signature(containerName, None,SharedAccessPolicy(AccessPolicy(None, todayPlusMonthISO, "rw"), None))

Here is the full code sample:

from azure.storage.blob import BlobService
import datetime
from azure.storage import AccessPolicy, CloudStorageAccount, SharedAccessPolicy

containerName = "testcontainer"
blobName = "testblob.txt"
azureStorageAccountName = "" # Removed for publishing to StackOverflow
azureStorageAccountKey = "" # Removed for publishing to StackOverflow
blob_service = BlobService(account_name=azureStorageAccountName, account_key=azureStorageAccountKey)
blob_service.create_container(containerName)
blob_service.put_block_blob_from_text(containerName,blobName,"Hello World")
today = datetime.datetime.utcnow()
todayPlusMonth = today + datetime.timedelta(30)
todayPlusMonthISO = todayPlusMonth.isoformat()
sasToken = blob_service.generate_shared_access_signature(containerName, None,SharedAccessPolicy(AccessPolicy(None, todayPlusMonthISO, "rw"), None))
url = "https://" + azureStorageAccountName + ".blob.core.windows.net/" + containerName + "/" + blobName + "?" + sasToken
print(url)

Any ideas how to fix this? Thank you!

The isoformat method appends microseconds to the string, AFAICT this is not valid in ISO8601.

If you modify your code like this:

todayPlusMonthISO = todayPlusMonth.replace(microsecond=0).isoformat() + 'Z'

The generated string becomes valid.

For example, before you had:

2016-01-03T21:04:10.545430

The change will transform it into the valid:

2016-01-03T21:04:10Z

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM