I can get subsriptions using token captured from browser:
Then I switch to Python and msal
.
I use the following code:
import msal
import requests
import sys
import json
data = json.load(open("parameters.json"))
config = {
"authority": f"https://login.microsoftonline.com/{data['tenant']}",
"client_id": data["client_id"],
"client_secret": data["client_secret"],
"scopes": [
"https://management.azure.com/.default",
]
}
app = msal.ConfidentialClientApplication(
data["client_id"],
authority=f"https://login.microsoftonline.com/{data['tenant']}",
client_credential=data["client_secret"],
)
result = app.acquire_token_for_client(scopes=[
"https://management.azure.com/.default",
])
if "access_token" in result:
print("success")
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id"))
sys.exit(-1)
headers = {
"Authorization": f"Bearer {result['access_token']}"
}
response = requests.get(
headers=headers, url="https://management.azure.com/subscriptions?api-version=2019-08-01")
if response.status_code == 200:
print(response.content)
else:
print(response.status_code)
However, I cannot get desired result:
success
b'{"value":[],"count":{"type":"Total","value":0}}'
The permissions are already granted:
I tried to add "https://management.azure.com//user_impersonation" to scope, but it fails with error:
AADSTS1002012: The provided value for scope https://management.azure.com//user_impersonation is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).
I reads about the "OBO" flow, but my app isn't supposed to need user interactions.
Ask: Does I miss something in the auth flow or permissions?
You need to assign at least Reader
role to the service principal before generating access token to call Azure Management API.
In my case, I registered one Microsoft Entra ID application and created one secret in it as below:
Now, I assigned Reader
role to the service principal under the management group as below:
When I ran your code after assigning role to service principal, I got the response successfully like this:
import msal
import requests
import sys
import json
data = json.load(open("parameters.json"))
config = {
"authority": f"https://login.microsoftonline.com/{data['tenant']}",
"client_id": data["client_id"],
"client_secret": data["client_secret"],
"scopes": [
"https://management.azure.com/.default",
]
}
app = msal.ConfidentialClientApplication(
data["client_id"],
authority=f"https://login.microsoftonline.com/{data['tenant']}",
client_credential=data["client_secret"],
)
result = app.acquire_token_for_client(scopes=[
"https://management.azure.com/.default",
])
if "access_token" in result:
print("success")
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id"))
sys.exit(-1)
headers = {
"Authorization": f"Bearer {result['access_token']}"
}
response = requests.get(
headers=headers, url="https://management.azure.com/subscriptions?api-version=2019-08-01")
if response.status_code == 200:
print(response.content)
else:
print(response.status_code)
Response: