question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BlobClient returns ClientAuthenticationError when Azure CDN is enabled

See original GitHub issue
  • Package Name: azure-storage-blob
  • Package Version: 12.10.0
  • Operating System: Ubuntu 20.04.4 LTS
  • Python Version: 3.9.5

Describe the bug Calling the BlobClient.exists method raises a ClientAuthenticationError when an Azure CDN account URL is used.

To Reproduce Steps to reproduce the behavior:

from azure.storage.blob import BlobServiceClient

ACCOUNT_NAME = "myaccount"
ACCOUNT_KEY = "myaccount-key"
CREDENTIAL = {"account_name": ACCOUNT_NAME, "account_key": ACCOUNT_KEY}

ACCOUNT_URL = f"https://{ACCOUNT_NAME}.blob.core.windows.net"
ACCOUNT_URL_CDN = f"https://{ACCOUNT_NAME}.azureedge.net"
ACCOUNT_URL_CDN_CUSTOM = f"https://static.{ACCOUNT_NAME}.com"

CONTAINER_NAME = "mycontainer"
BLOB_NAME = "path/to/image.png"

# The "standard" blob client endpoint
blob_client = BlobServiceClient(
    account_url=ACCOUNT_URL,
    credential=CREDENTIAL,
).get_blob_client(
    container=CONTAINER_NAME,
    blob=BLOB_NAME,
)

# This works! It returns True
blob_client.exists()

# Now, using the Azure CDN blob endpoint
blob_client_cdn = BlobServiceClient(
    account_url=ACCOUNT_URL_CDN,
    credential=CREDENTIAL,
).get_blob_client(
    container=CONTAINER_NAME,
    blob=BLOB_NAME,
)

# This does not work, it raises a `ClientAuthenticationError` error
blob_client_cdn.exists()

# Using a custom CDN (which is fully verified)
blob_client_cdn_custom = BlobServiceClient(
    account_url=ACCOUNT_URL_CDN_CUSTOM,
    credential=CREDENTIAL,
).get_blob_client(
    container=CONTAINER_NAME,
    blob=BLOB_NAME,
)

# This does not work, it raises a `ClientAuthenticationError` error
blob_client_cdn_custom.exists()

Expected behavior I would expect the client to authenticate correctly when using an Azure CDN or a custom CDN when the client authenticates correctly when using the standard blob endpoint.

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:23 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
kierandarcycommented, Apr 7, 2022

@vincenttran-msft I have generated a few more RequestIDs for you (just in case you didn’t manage to get to see the others - I guess were a few timezone apart).

# A successful response (without a CDN endpoint)
'x-ms-request-id': '369adfbf-801e-00b5-3d9c-4a2208000000'

# A failed response using the azuredge.net CDN endpoint
'x-ms-request-id': 'dc3b93de-e01e-0035-639d-4add0e000000'

# A failed response using a the CDN with a custom domain
'x-ms-request-id': '44f78dc3-701e-00b1-5d9d-4aaf0f000000'

These were generated using the example code in my original Steps to reproduce the behaviour (with account names and credentials updated).

This issue is preventing us from going live with our project. I would be willing to send you access tokens and keys (which I can recycle, if we do eventually get to go live) so you can reproduce the error yourself.

I have pasted the full output from running my Steps to reproduce the behaviour script if it helps.

In [2]: blob_client.exists()
Request URL: 'https://gamesmap.blob.core.windows.net/media/images/system/photo-2454235000000215156.png'
Request method: 'HEAD'
Request headers:
    'x-ms-version': '2020-10-02'
    'Accept': 'application/xml'
    'User-Agent': 'azsdk-python-storage-blob/12.9.0 Python/3.9.5 (Linux-5.13.0-39-generic-x86_64-with-glibc2.31)'
    'x-ms-date': 'Thu, 07 Apr 2022 16:31:26 GMT'
    'x-ms-client-request-id': '2ba19090-b690-11ec-b637-3d6a688c8c41'
    'Authorization': '*****'
Request body:
None
Response status: 200
Response headers:
    'Content-Length': '195963'
    'Content-Type': 'image/png'
    'Content-MD5': 'CHWOotVKq8/w7uG6kzMrbA=='
    'Last-Modified': 'Thu, 24 Mar 2022 09:54:18 GMT'
    'Accept-Ranges': 'bytes'
    'ETag': '"0x8DA0D7C436A3DDB"'
    'Server': 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0'
    'x-ms-request-id': '369adfbf-801e-00b5-3d9c-4a2208000000'
    'x-ms-client-request-id': '2ba19090-b690-11ec-b637-3d6a688c8c41'
    'x-ms-version': '2020-10-02'
    'x-ms-creation-time': 'Thu, 24 Mar 2022 09:54:18 GMT'
    'x-ms-lease-status': 'unlocked'
    'x-ms-lease-state': 'available'
    'x-ms-blob-type': 'BlockBlob'
    'Content-Disposition': ''
    'x-ms-server-encrypted': 'true'
    'x-ms-access-tier': 'Cool'
    'x-ms-access-tier-inferred': 'true'
    'Access-Control-Expose-Headers': 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,Content-MD5,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,Content-Disposition,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding'
    'Access-Control-Allow-Origin': '*'
    'Date': 'Thu, 07 Apr 2022 16:31:26 GMT'
Response content:
Body contains image data.
Out[2]: True

In [3]: blob_client_cdn.exists()
Request URL: 'https://gamesmap.azureedge.net/media/images/system/photo-2454235000000215156.png'
Request method: 'HEAD'
Request headers:
    'x-ms-version': '2020-10-02'
    'Accept': 'application/xml'
    'User-Agent': 'azsdk-python-storage-blob/12.9.0 Python/3.9.5 (Linux-5.13.0-39-generic-x86_64-with-glibc2.31)'
    'x-ms-date': 'Thu, 07 Apr 2022 16:32:12 GMT'
    'x-ms-client-request-id': '46beedbe-b690-11ec-b637-3d6a688c8c41'
    'Authorization': '*****'
Request body:
None
Response status: 403
Response headers:
    'Content-Length': '748'
    'Content-Type': 'application/xml'
    'Server': 'Microsoft-HTTPAPI/2.0'
    'X-Cache': 'TCP_MISS'
    'x-ms-request-id': 'dc3b93de-e01e-0035-639d-4add0e000000'
    'x-ms-error-code': 'AuthenticationFailed'
    'Access-Control-Expose-Headers': 'x-ms-request-id,x-ms-error-code,Content-Length,Date,Transfer-Encoding'
    'Access-Control-Allow-Origin': '*'
    'X-Azure-Ref-OriginShield': '0DBJPYgAAAABhQgjqImZdQY9Gfc3OysxBTE9OMjFFREdFMDExMwA2ZmJlNzM3NC03YWIzLTQzNTItODRiNC0xMGIwNjRhYjA4Zjc='
    'X-Azure-Ref': '0DBJPYgAAAACuOb0FYH0IT4JNCm3+NIjtTUFOMzBFREdFMDcxMwA2ZmJlNzM3NC03YWIzLTQzNTItODRiNC0xMGIwNjRhYjA4Zjc='
    'Date': 'Thu, 07 Apr 2022 16:32:12 GMT'
Response content:

---------------------------------------------------------------------------
ClientAuthenticationError                 Traceback (most recent call last)
<ipython-input-3-aade6ad209e1> in <module>
----> 1 blob_client_cdn.exists()

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/core/tracing/decorator.py in wrapper_use_tracer(*args, **kwargs)
     71             span_impl_type = settings.tracing_implementation()
     72             if span_impl_type is None:
---> 73                 return func(*args, **kwargs)
     74 
     75             # Merge span is parameter is set, but only if no explicit parent are passed

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/storage/blob/_blob_client.py in exists(self, **kwargs)
   1153         except HttpResponseError as error:
   1154             try:
-> 1155                 process_storage_error(error)
   1156             except ResourceNotFoundError:
   1157                 return False

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/storage/blob/_shared/response_handlers.py in process_storage_error(storage_error)
    175     try:
    176         # `from None` prevents us from double printing the exception (suppresses generated layer error context)
--> 177         exec("raise error from None")   # pylint: disable=exec-used # nosec
    178     except SyntaxError:
    179         raise error

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/storage/blob/_shared/response_handlers.py in <module>

ClientAuthenticationError: Operation returned an invalid status 'Forbidden'
ErrorCode:AuthenticationFailed

In [4]: blob_client_cdn_custom.exists()
Request URL: 'https://static.gamesmap.uk/media/images/system/photo-2454235000000215156.png'
Request method: 'HEAD'
Request headers:
    'x-ms-version': '2020-10-02'
    'Accept': 'application/xml'
    'User-Agent': 'azsdk-python-storage-blob/12.9.0 Python/3.9.5 (Linux-5.13.0-39-generic-x86_64-with-glibc2.31)'
    'x-ms-date': 'Thu, 07 Apr 2022 16:33:52 GMT'
    'x-ms-client-request-id': '82ea3e9c-b690-11ec-b637-3d6a688c8c41'
    'Authorization': '*****'
Request body:
None
Response status: 403
Response headers:
    'Content-Length': '748'
    'Content-Type': 'application/xml'
    'Server': 'Microsoft-HTTPAPI/2.0'
    'X-Cache': 'TCP_MISS'
    'x-ms-request-id': '44f78dc3-701e-00b1-5d9d-4aaf0f000000'
    'x-ms-error-code': 'AuthenticationFailed'
    'Access-Control-Expose-Headers': 'x-ms-request-id,x-ms-error-code,Content-Length,Date,Transfer-Encoding'
    'Access-Control-Allow-Origin': '*'
    'X-Azure-Ref-OriginShield': '0cRJPYgAAAACpFIw1TVNgRLsvkhpuRcTkTE9OMjFFREdFMDEyMgA2ZmJlNzM3NC03YWIzLTQzNTItODRiNC0xMGIwNjRhYjA4Zjc='
    'X-Azure-Ref': '0cRJPYgAAAABqi3bBiEA9RroHEa+DJoIcTUFOMzBFREdFMDcwOQA2ZmJlNzM3NC03YWIzLTQzNTItODRiNC0xMGIwNjRhYjA4Zjc='
    'Date': 'Thu, 07 Apr 2022 16:33:53 GMT'
Response content:

---------------------------------------------------------------------------
ClientAuthenticationError                 Traceback (most recent call last)
<ipython-input-4-6305c8075a85> in <module>
----> 1 blob_client_cdn_custom.exists()

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/core/tracing/decorator.py in wrapper_use_tracer(*args, **kwargs)
     71             span_impl_type = settings.tracing_implementation()
     72             if span_impl_type is None:
---> 73                 return func(*args, **kwargs)
     74 
     75             # Merge span is parameter is set, but only if no explicit parent are passed

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/storage/blob/_blob_client.py in exists(self, **kwargs)
   1153         except HttpResponseError as error:
   1154             try:
-> 1155                 process_storage_error(error)
   1156             except ResourceNotFoundError:
   1157                 return False

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/storage/blob/_shared/response_handlers.py in process_storage_error(storage_error)
    175     try:
    176         # `from None` prevents us from double printing the exception (suppresses generated layer error context)
--> 177         exec("raise error from None")   # pylint: disable=exec-used # nosec
    178     except SyntaxError:
    179         raise error

~/projects/games-map/.venv/lib/python3.9/site-packages/azure/storage/blob/_shared/response_handlers.py in <module>

ClientAuthenticationError: Operation returned an invalid status 'Forbidden'
ErrorCode:AuthenticationFailed

In [5]: 
1reaction
kierandarcycommented, Apr 12, 2022

I deleted the existing Microsoft CDN (classic) CDN, and created a new one with the Standard Verizon pricing tier. This has resolved the issue.

I will mark this issue as closed. Thank you for your time and patience @vincenttran-msft

Read more comments on GitHub >

github_iconTop Results From Across the Web

Azure Blob Storage fails to authenticate: "Make sure the value ...
Hi I am trying to upload a binary file (a blob for an excel file, actually) to my storage account but the client...
Read more >
AzureStorage Blob Server failed to authenticate the request ...
I got an error while uploading files into Azure Blob storage with metadata, the error is "Server failed to authenticate the request. Make...
Read more >
azure-storage-blob - PyPI
BlobLeaseClient - this client represents lease interactions with a ContainerClient or BlobClient . It provides operations to acquire, renew, release, change, ...
Read more >
Azure.Storage.Blobs 12.14.1 - NuGet
A blob in a container used via BlobClient. Learn more about options for authentication (including Connection Strings, Shared Key, Shared Key Signatures, Active...
Read more >
Enabling Azure CDN for the storage account
This blog post shows how to enable Azure Content Delivery Network (CDN) by creating a new CDN profile and CDN endpoint. Prerequisites.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found