Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you generate the signature for an Azure Blob storage SAS token in Python?

I am trying to build the SAS token required for a blob download URL in Python, following the instructions from MSDN.

My string to sign looks like:

r\n
2016-12-22T14%3A00%3A00Z\n
2016-12-22T15%3A00%3A00Z\n
%2Fblob%2Fmytest%2Fprivatefiles%2F1%2Fqux.txt\n
\n
\n
https\n
2015-12-11\n
\n
\n
\n
\n
_

I've added the newline symbols for clarity and the last line is supposed to be an empty line (with no newline at the end).

The Python method I use for signing the string is:

def sign(self, string):
    hashed = hmac.new(base64.b64decode(self.account_key), digestmod=sha256)
    hashed.update(string)
    base64_str = base64.encodestring(hashed.digest()).strip()
    return base64_str

The final URL I build looks like:

https://mytest.blob.core.windows.net/privatefiles/1/qux.txt?sv=2015-12-11&st=2016-12-22T14%3A00%3A00Z&se=2016-12-22T15%3A00%3A00Z&sr=b&sp=r&spr=https&sig=BxkcpoRq3xanEHwU6u5%2FYsULEtOCJebHmupUZaPmBgM%3D

Still, the URL fails with a 403. Any idea on what I am doing wrong?

like image 256
adrianp Avatar asked Dec 22 '16 14:12

adrianp


People also ask

How do I get a SAS token?

The simplest way to create a SAS token is to use the Azure Portal. In this case, you can navigate the various options graphically. To create a token, click the Shared access signature item in the Security + networking section of the left menu. You can grant different permissions and set start/expiry date and time.


2 Answers

The easiest way to generate SAS token in python is to leverage Azure Storage SDK for Python. Please consider following code snippet:

import time
import uuid
import hmac
import base64
import hashlib
import urllib
from datetime import datetime, timedelta
from azure.storage import (
    AccessPolicy,
    ResourceTypes,
    AccountPermissions,
    CloudStorageAccount,
)
from azure.storage.blob import (
    BlockBlobService,
    ContainerPermissions,
    BlobPermissions,
    PublicAccess,
)

AZURE_ACC_NAME = '<account_name>'
AZURE_PRIMARY_KEY = '<account_key>'
AZURE_CONTAINER = '<container_name>'
AZURE_BLOB='<blob_name>'

def generate_sas_with_sdk():
    block_blob_service = BlockBlobService(account_name=AZURE_ACC_NAME, account_key=AZURE_PRIMARY_KEY)    
    sas_url = block_blob_service.generate_blob_shared_access_signature(AZURE_CONTAINER,AZURE_BLOB,BlobPermissions.READ,datetime.utcnow() + timedelta(hours=1))
    #print sas_url
    print 'https://'+AZURE_ACC_NAME+'.blob.core.windows.net/'+AZURE_CONTAINER+'/'+AZURE_BLOB+'?'+sas_url

generate_sas_with_sdk()

Furthermore, to generate SAS token via plain python script, you can refer to the source code at https://github.com/Azure/azure-storage-python/blob/master/azure/storage/sharedaccesssignature.py#L173 for more hints.

like image 141
Gary Liu Avatar answered Oct 08 '22 13:10

Gary Liu


Update, with the latest storage python library, this is what I used to generate the sas token:

def generate_sas_token(file_name):
    sas = generate_blob_sas(account_name=AZURE_ACC_NAME,
                            account_key=AZURE_PRIMARY_KEY,
                            container_name=AZURE_CONTAINER,
                            blob_name=file_name,
                            permission=BlobSasPermissions(read=True),
                            expiry=datetime.utcnow() + timedelta(hours=2))

    logging.info('https://'+AZURE_ACC_NAME+'.blob.core.windows.net/'+AZURE_CONTAINER+'/'+file_name+'?'+sas)
    sas_url ='https://'+AZURE_ACC_NAME+'.blob.core.windows.net/'+AZURE_CONTAINER+'/'+file_name+'?'+sas
    return sas_url

Python 3.6 and azure-storage-blob package.

like image 28
kgalic Avatar answered Oct 08 '22 14:10

kgalic