问题
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?
回答1:
Based on the documentation (Please see Constructing the Signature String
section), the parameters passed to string to sign must be URL decoded. From the link:
To construct the signature string of a shared access signature, first construct the string-to-sign from the fields comprising the request, then encode the string as UTF-8 and compute the signature using the HMAC-SHA256 algorithm. Note that fields included in the string-to-sign must be URL-decoded.
Please use un-encoded parameter values in your string to sign and that should fix the problem.
回答2:
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.
回答3:
Here's an updated code snippet for Python3 and the updated Azure Storage Blob SDK:
from datetime import datetime, timedelta
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>'
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,permission=BlobPermissions.READ,expiry= datetime.utcnow() + timedelta(hours=1))
print('https://'+AZURE_ACC_NAME+'.blob.core.windows.net/'+AZURE_CONTAINER+'/'+AZURE_BLOB+'?'+sas_url)
来源:https://stackoverflow.com/questions/41285755/how-do-you-generate-the-signature-for-an-azure-blob-storage-sas-token-in-python