Azure/azure-sdk-for-python

ErrorCode:NoAuthenticationInformation when trying to authenticate to Azure Storage

acheng-01 opened this issue · 1 comments

  • Package Name: azure-storage-blob
  • Package Version: 12.19.1
  • Operating System: Linux (mariner-2.0)
  • Python Version: 3.8

Describe the bug
We have an AKS container that needs to authenticate with our Azure blob storage using managed identity. However, when the credential from DefaultAzureCredential() associated with the managed identity is passed through to BlobClientService(), I get the following error:

Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
RequestId:a3de1129-601e-0043-787f-9aa35b000000
Time:2024-04-29T21:54:40.3819603Z
ErrorCode:NoAuthenticationInformation
Content: <?xml version=\"1.0\" encoding=\"utf-8\"?>
<Error>
    <Code>
        NoAuthenticationInformation
    </Code>
    <Message>
        Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
        RequestId:a3de1129-601e-0043-787f-9aa35b000000
        Time:2024-04-29T21:54:40.3819603Z
    </Message>
</Error>

And checking that www-authenticate header doesn't yield me any useful information either:

'WWW-Authenticate': 'Bearer authorization_uri=https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/oauth2/authorize resource_id=https://storage.azure.com'

To Reproduce
Steps to reproduce the behavior:

  1. Create a user-assigned managed identity and associate it with a workload identity, like in the tutorial.
  2. Implement this storage code in the container:
from azure.storage.blob import BlobServiceClient

@deconstructible
class AzureStorage(BaseStorage):
    def __init__(self, **settings):
        super().__init__(**settings)
        self._service_client = None
        self._client = None

    def _get_service_client(self):
            if self.connection_string is not None:
                return BlobServiceClient.from_connection_string(self.connection_string)
    
            account_domain = self.custom_domain or "{}.blob.{}".format(
                self.account_name,
                self.endpoint_suffix,
            )
            account_url = "{}://{}".format(self.azure_protocol, account_domain)
    
            credential = None
            if self.account_key:
                credential = {
                    "account_name": self.account_name,
                    "account_key": self.account_key,
                }
            elif self.sas_token:
                credential = self.sas_token
            elif self.token_credential:
                credential = self.token_credential
            options = {}
            if self.api_version:
                options["api_version"] = self.api_version
            return BlobServiceClient(account_url, credential=credential, **options)

Setting the credential of our managed identity client id in the environment to be grabbed by the code in the first file:

from azure.identity import DefaultAzureCredential

AZURE_TOKEN_CREDENTIAL = DefaultAzureCredential()
  1. Run our CLI that will communicate with our API in the containers, which interacts with this code.

Expected behavior
For Azure Storage to successfully authenticate the credential that it is given without having that error message.

Additional context

  • We've confirmed that the workload identity loads the managed identity as AZURE_CLIENT_ID, so DefaultAzureCredential() should pick this up even without specifying it directly. In any case, even when I have hardcoded this value and used DefaultAzureCredential() directly in the storage code file, I am still getting that No Auth Info 401 error.
  • This code was previously running azure-storage-blob version 12.14.0, so I thought this was the issue. However, after updating the version there still is no improvement.

Guidance appreciated as I'm not sure if there is anything else to troubleshoot. Can provide any other info needed, thanks.

My issue is resolved. The problem was that the Dockerfile for the image did not copy in the settings properly, and as a result there was nothing passed to BlobServiceClient. Apologies for the troubles here.