Search code examples
pythonazureazure-storage-account

How to fix the 'AuthenticationFailed' error when using Odata for Azure storage account data queries in Python?


Question

I am following the official Azure documentation. My aim is to use Odata to do data queries for tables in Azure storage accounts. But the server always returns an error. I googled for a while. This seems to be related to the encryption of the request header. I am unable to resolve this issue. I would also appreciate any help.

My Code

import requests  
import datetime  
import hmac  
import base64  
from hashlib import sha256

account_name = '*****'
account_key = '*****'
table_name = '*****'

base_url = f'https://{account_name}.table.core.chinacloudapi.cn/{table_name}'
query_url = f"{base_url}()?$filter=PropertyName eq 'Value'"


now = datetime.datetime.utcnow()
date = now.strftime('%Y-%m-%d')


canonicalized_resource = f'/{account_name}/{table_name}'


string_to_sign = f'{date}\n{canonicalized_resource}'


signature = base64.b64encode(hmac.new(base64.b64decode(account_key), string_to_sign.encode('utf-8'), sha256).digest()).decode()


headers = {
    'Accept': 'application/json;odata=nometadata',
    'Content-Type': 'application/json',
    'x-ms-date': date,
    'Authorization': f'SharedKeyLite {account_name}:{signature}'
}

print(headers)

response = requests.get(query_url, headers=headers)


if response.status_code == 200:
    result = response.json()

else:
    print("", response.text)

Error Code

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>AuthenticationFailed</code>
  <message xml:lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:fa58da7b-2002-0058-4c5e-953c35000000
Time:2023-06-02T14:26:40.7310444Z</message>
</error>

Process finished with exit code 0

Does the problem occur because the wrong method of calculating the account key causes the problem? Please make corrections to my code

Google. ChatGPT, none of them have a correct result.


Solution

  • To query the table from Azure table storage using REST API using Python. You can use the below code.

    Code:

    import requests
    from hashlib import sha256
    import base64
    import hmac
    import datetime
    
    storageAccountName = '< Your storage account name>'
    storageKey='< Your storage account key >'
    
    filter_expression = "PartitionKey eq 'partitionkey1'"
    filter1=f"?$filter={filter_expression}"
    
    url = 'https://' + storageAccountName + '.table.core.windows.net/Employees()' + filter1
    version = '2021-02-12' # x-ms-version
    date = datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")  #x-ms-date
    parameters = 'Employees()'  #Mytablename
    
    CanonicalizedResources = '/' + storageAccountName + '/' + parameters
    CanonicalizedHeaders = 'x-ms-date:' + date 
    stringToSign = date + '\n' + CanonicalizedResources
    
    signature = base64.b64encode(hmac.new(base64.b64decode(storageKey), stringToSign.encode('utf-8'), sha256).digest()).decode()
    
    headers = {'x-ms-date': date,
           'x-ms-version': version,
           'Authorization': 'SharedKeyLite ' + storageAccountName + ':' + signature,
           'Accept': 'application/json;odata=nometadata '}
    
    # send the request
    response = requests.get(url, headers=headers)
    print (response)
    print (response.headers)
    print(response.text)
    

    Output:

    <Response [200]>
    {'Cache-Control': 'no-cache', 'Transfer-Encoding': 'chunked', 'Content-Type': 'application/json;odata=nometadata;streaming=true;charset=utf-8', 'Server': 'Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id': 'xxxxxxxxx', 'x-ms-version': '2021-02-12', 'X-Content-Type-Options': 'nosniff', 'Date': 'Mon, 05 Jun 2023 06:39:19 GMT'}
    {"value":[{"PartitionKey":"partitionkey1","RowKey":"rowkey1","Timestamp":"2023-03-16T11:12:28.2723247Z"}]}
    

    enter image description here

    Reference: Querying tables and entities (REST API) - Azure Storage | Microsoft Learn