0
votes

Using the Python azure-storage API I am expecting to be able to generate an Account SAS token which allows me to read and write blobs in any container in my storage account.

The generation of the SAS token goes without exception, but when I try to create a BlockBlobService using that SAS token and list some blobs for a given container, I get an AuthorizationPermissionMismatch error from Azure.

Am I understanding the concept of an Account SAS token correctly?

I have looked at a ton of documentation on Azure's "Getting Started" documentation for the Python Storage API, also I've looked through https://azure-storage.readthedocs.io/ref/azure.storage.blob.sharedaccesssignature.html quite a bit.

I have tried using azure.storage.blob.BlockBlobService.generate_account_shared_access_signature() with very permissive permissions and am still getting the exception.

I can confirm that azure.storage.blob.BlockBlobService.generate_container_shared_access_signature() does work fine, however my requirement is to generate a SAS Token irrespective of then container.

from azure.storage.blob import BlockBlobService
from azure.storage.models import AccountPermissions, ResourceTypes

bbs = BlockBlobService("myaccountname", "myaccountkey")

sas_token = bbs.generate_account_shared_access_signature(
                    ResourceTypes.CONTAINER + ResourceTypes.OBJECT + ResourceTypes.SERVICE,
                    AccountPermissions.READ + AccountPermissions.WRITE + AccountPermissions.LIST + AccountPermissions.CREATE,
                    datetime.utcnow() + timedelta(hours=1)
                    )

BlockBlobService(account_name="myaccountname", sas_token=sas_token).list_blobs("containername")
azure.common.AzureHttpError: This request is not authorized to perform this operation using this permission.
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.
RequestId:6a06b32e-f01e-005a-44e7-430c8b000000
Time:2019-07-26T19:22:02.7337249Z</Message></Error>

I expected to be able to call list_blobs() here no problem. How can I accomplish this without having to generate a SAS Token container by container?

1
Can you share the SAS token generated by your code?Gaurav Mantri
se=2019-07-26T22%3A39%3A38Z&sp=c&sv=2018-03-28&ss=b&srt=sco&sig=xUDGsgFYjV3K__________kdQXTNzlTm6i/38%3DAustin T
Your SAS token has just the create permission (sp=c). Can you try creating a SAS token with just list permission?Gaurav Mantri
Gaurav you are on to something. Just using the list permission does allow me to list the blobs in the container. This is a good start - now I have to figure out how to list, read, write and create!Austin T
Fantastic! I would recommend looking into the source code for the SDK to see why the permissions are not set properly. Your code looks fine to me.Gaurav Mantri

1 Answers

0
votes

I reviewed the definitions of the function generate_account_shared_access_signature and its parameters resource_types & permission, as the figures below.

Fig 1. The definitions of the function generate_account_shared_access_signature

enter image description here

Fig 2. The definitions of class ResourceTypes

enter image description here

Fig 3. The definitions of class AccountPermission

enter image description here

According to these definitions above, I think your issue was caused by using + syntax to combine these resource types and permissions as you want.

Here is my sample code which works fine without the issue as yours.

from azure.storage.blob import BlockBlobService
from azure.storage.models import AccountPermissions, ResourceTypes
from datetime import datetime, timedelta

account_name = '<your account name>'
account_key = '<your account key>'

bbs = BlockBlobService(account_name, account_key)

resource_types = ResourceTypes(service=True, container=True, object=True)
permission = AccountPermissions(read=True, write=True, delete=False, list=True, add=False, create=True, update=False, process=False, _str=None)
sas_token = bbs.generate_account_shared_access_signature(resource_types=resource_types, permission=permission, expiry=datetime.utcnow() + timedelta(hours=1))
blobs = BlockBlobService(account_name=account_name, sas_token=sas_token).list_blobs("<your container name>")
print(list(blobs))

Hope it helps.