Search code examples
azureauthenticationazure-sdksas-token

Error generating Azure container SAS token using Python SDK


I am trying to generate a container SAS token using the Python SDK for Azure. With the code below, I am getting this error: AuthenticationErrorDetail:Signature fields not well formed.

The generated token seems to have the time formatted incorrectly - is this a problem, and if it s, how do i fix it? Looks like this: se=2021-03-08T17%3A49%3A35Z&sp=rwlacu&spr=https&sv=2020-04-08&sr=c&sig=QhAFl1435SDFGSFDguiPA8%3D

I am pretty sure I should concatenate the sas_token with the container url, and I have tried that, but still get an error. Do I need to concatenate any more, for instance like container_url + "?sp=r&st=2021-03-08T12:12:14Z&" + sas_token? The SAS token i can generate in the portal, looks more like that at least.

import datetime
from azure.storage.blob import ContainerClient, BlobServiceClient, generate_container_sas, \
    ResourceTypes, AccountSasPermissions

storage_conn_str = "myconstring fetched from the portal"

blob_service_client = BlobServiceClient.from_connection_string(storage_conn_str)

start = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z" 
expiry = (datetime.datetime.utcnow() + datetime.timedelta(hours=3)).replace(microsecond=0).isoformat() + "Z"

sas_token = generate_container_sas(
    blob_service_client.account_name,
    container_name="containername",
    account_key=blob_service_client.credential.account_key,
    resource_types=ResourceTypes(container=True, object=True),
    permission=AccountSasPermissions(read=True, write=True, list=True, add=True, create=True,
                                     update=True),
    start=start,
    expiry=expiry,
    protocol="https"
)

print(sas_token)

cclient = ContainerClient.from_container_url(
    container_url="https://myblob.blob.core.windows.net/containername/",
    credential=sas_token)

print(cclient.get_account_information())

Solution

  • I believe the problem is coming because you're mixing both Service Shared Access Signature and Account Shared Access Signature.

    Please try the following code:

    sas_token = generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(container=True, object=True),
        permission=AccountSasPermissions(read=True, write=True, list=True, add=True, create=True,
                                        update=True),
        start=start,
        expiry=expiry,
        protocol="https"
    )
    

    This will generate the Account SAS. I used this code to read container properties like following:

    cclient = ContainerClient.from_container_url(
    container_url="https://account.blob.core.windows.net/container/",
    credential=sas_token)
    print(cclient.get_account_information())
    

    And I did not get any error.

    Please ensure to import generate_account_sas though.