Search code examples
azureazure-active-directoryazure-managed-identity

azure identity to get graph api


I am currently using the below code to get the service principal of data factory. this code is working fine locally and I am able to retrieve the serviceprincipal. The issue with this is the way i get identity. I need to provide client details (which is a demo app registration created in AD for test purposes.)

try:
    app = msal.ConfidentialClientApplication(
        self.input_client_id, authority=self.input_authority,
        client_credential=self.input_secret,
        )
    result = app.acquire_token_for_client(scopes=self.input_scope)
    
    input_endpoint = "https://graph.microsoft.com/v1.0/servicePrincipals?$filter=startswith(displayName,'{}')".format(datafactory_name)
    graph_data = requests.get(
    input_endpoint,
    headers={'Authorization': 'Bearer ' + result['access_token']},).json()

I want to avoid doing that as I use devops pipeline to run this code in container registry and want to avoid giving the secret as a variable. The pipeline uses a service connection and I login using the Azure CLI task.

Is there a way to replace the above code to get client credential.

Below are some of the trials done locally already:

Login locally using the azure devops service connection to mimic devops pipeline to test

az login --service-principal --username <clientid> --password <client_secret> --tenant <tenant_id>  
from azure.common.credentials import get_azure_cli_credentials

credentials, subscription = get_azure_cli_credentials()

app = msal.ConfidentialClientApplication(
self.input_client_id, authority=self.input_authority,
client_credential=credentials,
)

This gives an error: 'error': 'invalid_client'

  1. Another approach, I read the accessToken.json file in '.azure' folder in my local. I got the access_token value in json which was the <client_secret> and then replaced the client_credential with this value. This worked. But then in devops. I will have to create the .azure profile (which I assume the devops task AzureCLI@2 will create) and mount it to the docker. Also, the accessToken was having the client_secret, not the actual token(long string). Is there a better way to do it in the code?

Thanks for your time!


Solution

  • It may be due to client_secret when it contains special characters. One workaround is to go to the Azure portal and keep generating new secrets until you get one that does not have special characters in it. For more information, see here.

    And if you would like to use Azure Identity for Python, you could get access token with AzureCliCredential Class.

    from azure.identity import AzureCliCredential
    
    credential = AzureCliCredential()
    access_token = credential.get_token(scopes=["..."])