Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature with error code 403

Question:

I want to connect to my azure storage explorer and read the table data using python.It’s running on Azure storage emulator.My code is like this;

storage_account_name = 'devstoreaccount1'
storage_account_key = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='
#api_version = '2016-05-31'
api_version = '2017-04-17'
request_time = datetime.datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT')
print(request_time)

string_params = {
    'verb': 'GET',
    'Content-MD5': '',
    'Content-Type': '',
    'Date': request_time,
    'CanonicalizedResource': '/' + storage_account_name +'/'+storage_account_name + 'ncomp:list' #note, it should be 'ncomp:list', no '/'
}

string_to_sign = (string_params['verb'] + "n" +
               string_params['Content-MD5'] + "n" +
               string_params['Content-Type'] + "n" +  
               string_params['Date'] + "n" +  
               string_params['CanonicalizedResource'])

signed_string = base64.b64encode(hmac.new(base64.b64decode(storage_account_key), msg=string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()).decode()

headers = {
    'Date' : request_time,
    'x-ms-version' : api_version,
    'Authorization' : ('SharedKey ' + storage_account_name + ':' + signed_string)
}

url = ('http://127.0.0.1:10002/' + storage_account_name + '?comp=list')

r = requests.get(url, headers = headers)

print(r.status_code)
print(r.content)
    

I referred to this.[https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key#constructing-the-canonicalized-headers-string:~:text=Table%20service%20(Shared%20Key%20authorization)]

But, it gives this error.

403
b'<?xml version="1.0" encoding="utf-8"?><m:error xmlns_m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:code>AuthenticationFailed</m:code><m:message xml_lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.nRequestId:fdcea5c3-e071-4745-87dd-620848f550denTime:2023-03-03T05:07:01.4244873Z</m:message></m:error>'

I tried doing changes to the signed string.But it didn’t succeed.

Does anyone know what’s wrong with my code?

Asked By: Asu

||

Answers:

The above code you shared is for listing the containers in the Azure Storage Emulator using shared key authorization and it does not provide a way to connect to a table storage and read its data.

I check the same thing in MS-DOCS, I couldn’t find functionality to read the data from the table storage.

You can find the below code with azure-data-tables package which worked for me, to read the data from the table of the azure storage emulator.

Code:

from azure.data.tables import TableServiceClient

# Set up the connection to the Azure Table storage account
connection_string = 'DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;AccountName=devstoreaccount1;AccountKey=<account key>;'
table_service_client = TableServiceClient.from_connection_string(connection_string)

# Get a reference to the table
table_name = '<Your table name>'
table_client = table_service_client.get_table_client(table_name)

query_filter = "PartitionKey eq 'key1'"
entity = table_client.query_entities(query_filter=query_filter)
for prop in entity:
    print(f'{prop},n{prop.metadata}')

Output:
enter image description here

Reference:
Azure Tables client library for Python | Microsoft Learn

Answered By: Venkatesan