0

Following the quickstart here

I use DefaultAzureCredential My code

import os
import uuid
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient

try:
    account_url = 'https://kindglacierblob.blob.core.windows.net'
    default_credential = DefaultAzureCredential()
    blob_service_client = BlobServiceClient(account_url, credential=default_credential)
    container_name = str(uuid.uuid4())
    container_client = blob_service_client.create_container(container_name)

except Exception as e:
    print(e) # See error details below

Server failed to authenticate the request.

<Error>
<Code>InvalidAuthenticationInfo</Code>
<Message>
    Server failed to authenticate the request. 
    Please refer to the information in the www-authenticate header.
    RequestId:23153837-001e-0019-6585-855a4a000000
    Time:2023-05-13T10:28:57.2758247Z
</Message>
<AuthenticationErrorDetail>
    Issuer validation failed. Issuer did not match.
</AuthenticationErrorDetail>
</Error>

When I print e.response.request.url:

'https://kindglacierblob.blob.core.windows.net/40803991-619c-4cc6-8931-cfdbae302438?restype=container'

When I print e.response.request.headers:

{   'Accept': 'application/xml',
    'Authorization': 'Bearer '
                     'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ii1LSTNROW5OUjdiUm9meG1lWm9YcWJIWkdldyIsImtpZCI6Ii1LSTNROW5OUjdiUm9meG1lWm9YcWJIWkdldyJ9.eyJhdWQiOiJodHRwczovL3N0b3JhZ2UuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvY2M5ZjFhMTgtMDk4Yy00YWE0LWE1MmUtZjA3YTk3N2ZhMTIwLyIsImlhdCI6MTY4Mzk3MjQ0OSwibmJmIjoxNjgzOTcyNDQ5LCJleHAiOjE2ODM5Nzc3MTIsImFjciI6IjEiLCJhaW8iOiJBVlFBcS84VEFBQUFBT0FkU1RPZnNHMTNtdmV6M1VrVzlzakVpK0lRckxVanU4SGxZSG9EM3JHbkFJOExJQUdLclYwbGtEMmp2SFBLWk5Oa2h1YU1GdGFMRzd2aVA1SEUxZ1hDcVo1dmVyaEFnL0xTbG9PdUpIQT0iLCJhbHRzZWNpZCI6IjE6bGl2ZS5jb206MDAwMzAwMDBBQzU4MkZCNSIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYiLCJhcHBpZGFjciI6IjAiLCJlbWFpbCI6InRoZXJlZHBlYUBnbWFpbC5jb20iLCJmYW1pbHlfbmFtZSI6IkFuZGVyc29uIiwiZ2l2ZW5fbmFtZSI6Ik5hdGUiLCJncm91cHMiOlsiNGI2MDEyNTQtMGJmMi00ZDZiLWI3NzEtMmUyNWIxOGZjMDE2Il0sImlkcCI6ImxpdmUuY29tIiwiaXBhZGRyIjoiNzEuMjExLjE4NS4yMzQiLCJuYW1lIjoiTmF0ZSBBbmRlcnNvbiIsIm9pZCI6ImQ2ZTg0ODcxLTBkZWQtNDJlYS04YTNhLTY2NjYxMTMwMzZjMyIsInB1aWQiOiIxMDAzM0ZGRjk0OTI3QzFCIiwicmgiOiIwLkFSZ0FHQnFmekl3SnBFcWxMdkI2bDMtaElJR21CdVRVODZoQ2tMYkNzQ2xKZXZFWUFPSS4iLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJzdWIiOiJJX3BUeUJRNDZLdDNBUkJ6eEpQYnYyQklUbWlTbjdYbzFiNTN3ZDZITlBjIiwidGlkIjoiY2M5ZjFhMTgtMDk4Yy00YWE0LWE1MmUtZjA3YTk3N2ZhMTIwIiwidW5pcXVlX25hbWUiOiJsaXZlLmNvbSN0aGVyZWRwZWFAZ21haWwuY29tIiwidXRpIjoidUtGbnU3eHpqVVM1QnFpMWVGMFFBQSIsInZlciI6IjEuMCJ9.qM56mzD09cB1oLW2sa-aZiPsgCCr7cnZ8mlYv5cTHK8pZLlEyXf5404EVrIas7N5tPhiBFL6qq_7znD-4NPFBFK0qWdGIi4BN66T1c5U81wJQl1VgDK4KoHxh2LmUtfYiDHne8LKQ7dLO_WSd-LWb_eTVSEg_0rEOxWjRpcgwRSrvYw98sWdIoIp0doPAmqXeI_IQcDdvWEu6rSMsTd74CjMRaTwFAFpclDazzCWz_kFOMRfaro4s03Ki-7CYRZj-JI49mKvCThXrphLBfOU2B_VrEg4HJNwOb55nFc2WS5l9r0WBh1AlhQa9i7NvmP-OoEZi8gox4HMJeKz6h-pDg',
    'User-Agent': 'azsdk-python-storage-blob/12.16.0 Python/3.11.2 '
                  '(Windows-10-10.0.19044-SP0)',
    'x-ms-client-request-id': 'f69db4e3-f178-11ed-b2a7-f89e94c65957',
    'x-ms-date': 'Sat, 13 May 2023 10:28:55 GMT',
    'x-ms-version': '2022-11-02'}

When I print e.response.headers (notice the value of the www-authenticate header):

{   'Content-Length': '402',
    'Content-Type': 'application/xml',
    'Date': 'Sat, 13 May 2023 10:28:56 GMT',
    'Server': 'Microsoft-HTTPAPI/2.0',
    'WWW-Authenticate': 'Bearer '
                        'authorization_uri=https://login.microsoftonline.com/0091f901-8eb9-49ad-a413-3bd58cb1aff0/oauth2/authorize '
                        'resource_id=https://storage.azure.com',
    'x-ms-error-code': 'InvalidAuthenticationInfo',
    'x-ms-request-id': '23153837-001e-0019-6585-855a4a000000'}

Similar questions/ what I tried:

I assigned myself "Storage Blob Data Contributor" for the kindglacierblob Blob, as described here (screenshot below)

screenshot of Azure Portal IAM showing I assigned myself "Storage Blob Data Contributor" for the kindglacierblob Blob

Running with Visual Studio Code I logged in using the VS Code "Azure Account Extension", as shown in the screenshot below:

screenshot showing logged in using the VS Code "Azure Account Extension"

I tried to login by opening Azure CLI in a new VS Code Terminal, but I get an unrelated error:

Error: Cannot find module 'vscode'
Require stack:
- c:\Users\nateanderson\.vscode\extensions\ms-vscode.azure-account-0.11.4\dist\cloudConsoleLauncher.js

With the popup:

The terminal process "node.exe '-e', 'require('c:\\Users\\nateanderson\\.vscode\\extensions\\ms-vscode.azure-account-0.11.4\\dist\\cloudConsoleLauncher').main()'" terminated with exit code: 1.
Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
  • Thanks for your help @TomW, I used `pprint` to output my headers, including `WWW-authenticate`, which contains `authorization_uri`, but I don't see two GUIDs in the `authorization_uri`, only one? (36 characters including hyphens, right?). `authorization_uri=https://login.microsoftonline.com/0091f901-8eb9-49ad-a413-3bd58cb1aff0/oauth2/authorize` – Nate Anderson May 13 '23 at 11:15
  • 1
    Oops - I'm seeing things - possibly something to do with fat-fingering the scrollbar on my mobile. When I re-read the question on a good-sized screen, nothing untoward here. Comment retracted. – Tom W May 13 '23 at 11:17
  • I appreciate your eyes on the question anyway, I feel like I must be making some simple mistake here... – Nate Anderson May 13 '23 at 11:18

1 Answers1

1

When I decode your JWT in https://jwt.io I get:

screenshot of the issuer claim of the decoded JWT

and looking at the idp claim:

screenshot of the idp claim of the decoded JWT

This to me looks as though the DefaultAzureCredential has picked up an active login to your Microsoft account that has been issued by the Windows Live authorization server, rather than the Azure Active Directory authorization server, and that would seem to be different enough that this isn't good enough for Azure - even though they clearly share the same identity database since you can sign into both with your Microsoft account. I'm not familiar with the Python SDK so can't suggest what options might be available to fine-tune this.

EDIT

You can decode the JWT used in the Authorization header to see username is being used to log in (screenshot below)

As explained in the comments, it was not the username you expected.

take the Authorization JWT token and decode to find out which user is being used to authorize your access to Blob Storage

With the Python azure-login library, you can specify the username you really want to use with the shared_cache_username keyword argument, as shown here: enter image description here

Analogous to the .NET DefaultAzureCredentialOptions.SharedTokenCacheUsername property, the Python shared_cache_username argument is described as:

Preferred username for azure.identity.SharedTokenCacheCredential. Defaults to the value of environment variable AZURE_USERNAME, if any.

Therefore another option (instead of setting shared cache username in your code) is to SET the AZURE_USERNAME environment variable (which can be done using Git Bash (shown below), or Windows cmd.exe):

export AZURE_USERNAME=<your_username>

Or if you're using VSCode to develop and debug, you could add the environment variable into your launch.json file, you could try adding this:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Current File",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal",
      "env": {
        "AZURE_USERNAME": "{your username here}"
      },
    ...

screenshot of launch.json file using the "env" to set environment variable "AZURE_USERNAME"

Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
Tom W
  • 5,108
  • 4
  • 30
  • 52
  • I think you're onto something, when I decode the JWT payload (found in `e.response.request.headers['Authorization']`), I see "email": "theredpea@gmail.com" -- that's my **personal email** (my personal email *does have* a Microsoft account, but does not have access to this blob storage; I gave access to my **work account/work email**)... Once we find the details to fix this (or at least verify it) I'll mark your answer correct. I'll try to a) login with my work account.... b) giving my personal email access to this blob storage... (not ideal) – Nate Anderson May 13 '23 at 11:45
  • 1
    ['`SharedTokenCacheUsername`](https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredentialoptions.sharedtokencacheusername#azure-identity-defaultazurecredentialoptions-sharedtokencacheusername) on `DefaultAzureCredentialOptions` looks like what you want, assuming the python SDK supports it. – Tom W May 13 '23 at 13:27
  • Thanks, @TomW! You left me to the issue and suggested the right fix. I edited your answer to include the details of the fix -- please undo my edits if you don't like them. – Nate Anderson May 13 '23 at 16:19