1gentlemann
1gentlemann

Reputation: 176

Microsoft Graph API Python SDK "Insufficient privileges to complete the operation."

i'm trying to get user data from AAD using Microsoft Graph API Python SDK. App registration that i have in company tenant has the followiing API permissions: enter image description here

I'm using the following piece of code to get user's details from AAD:

from azure.common.credentials import ServicePrincipalCredentials
from azure.graphrbac import GraphRbacManagementClient

credentials = ServicePrincipalCredentials(
    client_id="appClientId",
    secret="appClientSecret",
    resource="https://graph.windows.net",
    tenant = 'companyTenant'
)

tenant_id = 'companyTenantId'

graphrbac_client = GraphRbacManagementClient(
    credentials,
    tenant_id
)

user = graphrbac_client.users.get("myUserObjectId")

And get "azure.graphrbac.models.graph_error_py3.GraphErrorException: Insufficient privileges to complete the operation."

I'm using Python 3.10.5 and my app service should be able to get data of any user from AAD.

What am i doing wrong here?

Upvotes: 0

Views: 907

Answers (3)

1gentlemann
1gentlemann

Reputation: 176

Okay, so it came out that the issue was that i was using wrong SDK, the one that i've used was working with the AAD graph but i need Microsoft.Graph (if the permission that i've granted to the app registration would be of the AAD Graph type - then it would work, but since AAD Graph cannot be assigned anymore to the app registration since it is deprecated i've assigned Microsoft.Graph permission). So the fix was to use another SDK from MS (that is currenty in preview) and it worked for me, here is the code:

from azure.identity import ClientSecretCredential
from msgraph.core import GraphClient

credential = ClientSecretCredential(tenant_id='tenantId',client_secret='appRegClientId',client_id='appRegClientSecret')
client = GraphClient(credential=credential)

result = client.get('/users')                   # gets all users
# result = client.get('/users/userObjectId')    # gets a certain user by it's objectId
# result = client.get('/users/email')           # gets a certain user by it's email address

print(result.json())

Upvotes: 1

Sridevi
Sridevi

Reputation: 22362

I tried to reproduce the same in my environment and got below results:

I created one Azure AD application and granted API permissions like below:

enter image description here

When I ran the same code as you, I got same error as below:

from azure.common.credentials import ServicePrincipalCredentials
from azure.graphrbac import GraphRbacManagementClient

credentials = ServicePrincipalCredentials(
    client_id="appClientId",
    secret="appClientSecret",
    resource="https://graph.windows.net",
    tenant = 'companyTenantId'
)

tenant_id = 'companyTenantId'

graphrbac_client = GraphRbacManagementClient(
    credentials,
    tenant_id
)

user = graphrbac_client.users.get("myUserObjectId")

Response:

enter image description here

I agree with Vicky kumar that graph.windows.net is deprecated and you need to change/migrate to https://graph.microsoft.com.

But the libraries that you are using won't support this resource that results error as below:

enter image description here

Your current library azure.graphrbac only supports resource as graph.windows.net that needs AAD graph permissions:

enter image description here

To resolve the error, you can make use of below code by installing urllib3 library beforehand:

import  urllib3
uri = "https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token"
payload= {
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'login.microsoftonline.com',
'client_id': '3de439c4-570d-4534-bxxb-e3axxx5d', #Your AppID
'scope': 'https://graph.microsoft.com/.default',
'client_secret': 'T2Y8Q~wYQxxxxxxxxxxOODUtFxajo', #Your client secret
'grant_type': 'client_credentials'
 }

http = urllib3.PoolManager()
response = http.request('POST', uri, payload)
my_dict = eval(response.data)
token = f"{my_dict['token_type']}  {my_dict['access_token']}"
#print(token)

uri5 = 'https://graph.microsoft.com/v1.0/users/myUserID'
payload5 = {'Authorization':token,'Host':'graph.microsoft.com','ConsistencyLevel':'eventual'}
https = urllib3.PoolManager()
response5 = http.request('GET', uri5, headers=payload5)
print(response5.data)

When I ran the above code, I got the user details successfully as below:

enter image description here

Upvotes: 1

vicky kumar
vicky kumar

Reputation: 738

Looks like the resource are trying to reach out is incorrect , https://graph.windows.net is used when you want to connect to AAD graph , please check the docs for more info - https://learn.microsoft.com/en-us/previous-versions/azure/ad/graph/howto/azure-ad-graph-api-operations-overview.

Could you please try by using the resource = graph.microsoft.com .

graph.microsoft.com is correct endpoint for graph . please see the doc - https://learn.microsoft.com/en-us/graph/use-the-api

Hope this helps

Thanks

Upvotes: 1

Related Questions