Search code examples
pythonazuremicrosoft-graph-apiauthorizationazure-ad-graph-api

MS Graph API Insufficient permissions when using Python SDK, sufficient when doing normal HTTP requests


I'm trying to migrate my usage of Graph API from doing http requests via requests to using the Python SDK. I was using the acquire_token_by_username_password method and requests were going through correctly. When migrating to utilize the Python SDK, I'm creating my client like:

credential = UsernamePasswordCredential(
        client_id=self._client_id,
        username=username,
        password=password,
    )
    return GraphServiceClient(credential, self._scopes)

and then attempting a request like:
await client.users.get(request_configuration=request_configuration)

However, with the same credentials as I was using in the HTTP method, I'm getting:

  APIError
        Code: 403
        message: None
        error: MainError(additional_data={}, code='Authorization_RequestDenied', details=None, inner_error=InnerError(additional_data={}, client_request_id='53e56211-cd3d-47d5-b3fb-b6dacd6088a8', date=DateTime(2024, 2, 25, 11, 10, 15, tzinfo=Timezone('UTC')), odata_type=None, request_id='4b92be4e-d60a-4040-bcb4-e8d11a636879'), message='Insufficient privileges to complete the operation.', target=None)

I have attempted re consenting for the (delegated) permissions in azure; not sure what else can I do.


Solution

  • The error usually occurs if the user or service principal does not have required permissions or roles to perform the operation.

    Initially, I too got same error when I passed User.Read in scopes that is not enough to list users:

    enter image description here

    To resolve the error, you need to add at least User.Read.All Delegated permission in your app registration by granting admin consent to it:

    enter image description here

    When I ran below modified code by changing scope value to User.Read.All, I got response with users successfully like this:

    import asyncio
    from msgraph import GraphServiceClient
    from azure.identity import UsernamePasswordCredential
    
    credential = UsernamePasswordCredential(
           client_id="appId",
           username="[email protected]",
           password="xxxxxxxxxx",
       )
    
    scopes=['User.Read.All']
    client = GraphServiceClient(credential, scopes=scopes)
    
    async def get_users():
        try:
            users = await client.users.get()
            for user in users.value:
                print(user.display_name)
    
        except Exception as e:
            print(e)
    
    asyncio.run(get_users())
    

    Response:

    enter image description here

    Reference: List users - Microsoft Graph