Search code examples
azureazure-active-directorymicrosoft-graph-apimicrosoft-graph-sdksazure-python-sdk

How to replicate `az ad app list` using Azure Python SDK


How do I replicate az ad app list using the official Azure Python SDK?

The answer which I found included using azure-graphrbac but it's deprecated. The official docs says to use Microsoft Graph API instead, but I couldn't find a proper solution.

Update:

import asyncio

from azure.identity import DefaultAzureCredential
from msgraph import GraphServiceClient
from dotenv import load_dotenv

load_dotenv()

credential = DefaultAzureCredential()
client = GraphServiceClient(credential)


async def main():
    result = await client.applications.get()
    return result


asyncio.run(main())

Here's a code which I came up with, but running this gives me an error.

msgraph.generated.models.o_data_errors.o_data_error.ODataError:
        APIError
        Code: 403
        message: None
        error: MainError(additional_data={}, code='Authorization_RequestDenied', details=None, inner_error=InnerError(additional_data={'date': DateTime(2023, 12, 7, 5, 41, 17, tzinfo=Timezone('UTC'))}, client_request_id='ee33797c-1ae4-4a00-99bd-5cf8ed30301b', date=None, odata_type=None, request_id='b5d36ffa-5cdc-4c7c-aaa9-9aef55bcf5ab'), message='Insufficient privileges to complete the operation.', target=None)

I followed this article to setup an application and assigned 'Reader' role in the IAM permission.

Any ideas?


Solution

  • The error usually occurs if the service principal does not have proper permissions or roles to perform the operation. Note that, Reader role works to manage only Azure resources under subscription level, not tenant level.

    To resolve the error, you need to add Application.Read.All Microsoft Graph permission in your app registration and make sure to grant admin consent to it like this:

    enter image description here

    In my case, I ran below modified python code and got response with application details successfully:

    import asyncio
    
    from azure.identity import ClientSecretCredential
    from msgraph import GraphServiceClient
    from dotenv import load_dotenv
    import os
    
    load_dotenv()
    
    tenant_id = os.getenv("AZURE_TENANT_ID")
    client_id = os.getenv("AZURE_CLIENT_ID")
    client_secret = os.getenv("AZURE_CLIENT_SECRET")
    
    credential = ClientSecretCredential(
        tenant_id=tenant_id,
        client_id=client_id,
        client_secret=client_secret
    )
    
    client = GraphServiceClient(credential)
    
    async def main():
        result = await client.applications.get()
        applications = result.value
        for app in applications:
            print("App Name:", app.display_name)
            print("App ID:", app.app_id)
            print("--------------------------------------------------")
    
    asyncio.run(main())
    

    Response:

    enter image description here