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?
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:
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: