Search code examples
pythonazure-devopsazure-devops-rest-api

Authentication via `az login` for Azure DevOps in custom script


I'm trying to create a python script to interact with Azure DevOps and I have problem with authentication. I don't want to use PAT. When I try to use DefaultAzureCredential from azure.identity, I get following error: 'DefaultAzureCredential' object has no attribute 'signed_session'

from azure.identity import DefaultAzureCredential
from azure.devops.connection import Connection

credential = DefaultAzureCredential()
connection = Connection(base_url="https://dev.azure.com/org_name", creds=credential)
core_client = connection.clients.get_core_client()
projects = core_client.get_projects()

I found another way. This works but I noticed it is recommended to use azure.identity instead of azure.common.credentials.get_azure_cli_credentials().

from azure.common.credentials import get_azure_cli_credentials
from azure.devops.connection import Connection

credential = get_azure_cli_credentials()[0]
connection = Connection(base_url="https://dev.azure.com/org_name", creds=credential)
core_client = connection.clients.get_core_client()
projects = core_client.get_projects()

Am I doing something wrong with azure.identity or is there a better way?

UPDATE: get_azure_cli_credentials doesn't work with new version of az cli

This method is not working for azure-cli-core>=2.21.0 (released in March 2021). It is now recommended to authenticate using https://pypi.org/project/azure-identity/ and AzureCliCredential.


Solution

  • I noticed that in a few places (az devops CLI extension, Azure SDK for Python, az CLI) the msrest library is used. the library is marked as deprecated, but if it is used by Microsoft, I think it makes sense to use it until the use of DefaultAzureCredential becomes possible with Azure DevOps SDK. I managed to create a credential object by passing the token to BasicTokenAuthentication from msrest.authentication.

    from azure.identity import DefaultAzureCredential
    from msrest.authentication import BasicTokenAuthentication
    from azure.devops.connection import Connection
    
    credential = DefaultAzureCredential()
    token = credential.get_token('499b84ac-1321-427f-aa17-267ca6975798/.default')
    credentials = BasicTokenAuthentication({'access_token': token.token})
    organization_url = 'https://dev.azure.com/myorg'
    connection = Connection(base_url=organization_url, creds=credentials)
    
    core_client = connection.clients.get_core_client()
    get_projects_response = core_client.get_projects()
    if get_projects_response:
        for project in get_projects_response:
            print(project.name)
    

    Output:

    myproject
    

    The example from the documentation using PAT also works when PAT is replaced with a token