BlueSky
BlueSky

Reputation: 1539

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!

Upvotes: 3

Views: 2668

Answers (1)

Nico Erfurth
Nico Erfurth

Reputation: 3453

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

Upvotes: 3

Related Questions