1

I have my Power BI application registered in Azure Active Directory with select API permissions (such as User.Read). I've done my best to follow the MSAL documentation, along with searching this website and others and trying some code snippets I've found but I am not having any luck. I was unable to generate a token using a public client application and I made it a bit further with a confidential one - I generated a token and sent the request to the website and am stuck here as I'm not sure what the error is specifically. I'm also not sure how much of the request text I can show as I'm not sure what is confidential and what is not.

I've spent hours trying to connect to the PBI REST API using MSAL in a variety of ways based on my research mentioned above and figured it was time to reach out for help. Thank you in advance!

Here is my code, with specific ID's removed:

#Import msal and requests
import msal
import requests

#Multiple parameters that will be needed
client_id = 'client id code'
client_credential = 'client secret code'
authority = 'https://login.microsoftonline.com/tenant id code'
redirect_uri = 'https://login.microsoftonline.com/common/oauth2/nativeclient'
power_bi_api = 'https://analysis.windows.net/powerbi/api/'
power_bi_api_root = 'https://api.powerbi.com/'
scopes_list = [
    power_bi_api + 'User.Read',
    power_bi_api + 'Dashboard.Read.All',
    power_bi_api + 'Dataset.Read.All',
    power_bi_api + 'Gateway.Read.All',
    power_bi_api + 'Workspace.Read.All'
]
endpoint = 'https://login.microsoftonline.com/tenant id code/oauth2/v2.0/authorize'

#Create a confidential client application
app = msal.ConfidentialClientApplication(
    client_id = client_id,
    client_credential = client_credential,
    authority = authority
)

#Generate a token
token_gen = app.acquire_token_for_client(
    scopes = 'https://analysis.windows.net/powerbi/api/.default'
)
#Returns token_type = Bearer, and gives an access_token
#I'm not sure why I need to use .default here instead of scopes_list,
#  but it didn't work otherwise

#Here is where I'm stuck
header = {'Authorization': 'Bearer ' + token_gen['access_token']}
api_out = requests.get(endpoint, headers = header)
#Returns status code 200
Bill
  • 11
  • 1

1 Answers1

0

I was able to resolve this with help from an AAD admin at my workplace. The admin was able to provide admin permission to the app I had registered. I then used the below code to get a token directly using my username and password instead of what I had done in the question:

import msal

#Client ID from Azure Active Directory (AAD)
clientID = 'my-client-id'
#Authority is https://login.microsoftonline.com/ and tenant ID (from AAD)
authority = 'https://login.microsoftonline.com/my-tenant-id'
#Root address for PBI app
pbiAPI = 'https://analysis.windows.net/powerbi/api/'
#List of scopes available in AAD - must have all scopes listed in AAD
scopesList = [
    'https://graph.microsoft.com/User.Read',
    'https://graph.microsoft.com/User.ReadBasic.All',
    pbiAPI + 'Dashboard.Read.All',
    pbiAPI + 'Dataflow.Read.All',
    pbiAPI + 'Dataset.Read.All',
    pbiAPI + 'Gateway.Read.All',
    pbiAPI + 'Pipeline.Read.All',
    pbiAPI + 'Report.Read.All',
    pbiAPI + 'Workspace.Read.All'
]
    
#Create a public client application
app = msal.PublicClientApplication(
    client_id = clientID,
    authority = authority
    )

#Create an object to hold token acquisition results
result = None

#If there is nothing in the result object, acquire a token using username/password
if not result:
    result = app.acquire_token_by_username_password(
        username = 'myusername',
        password = 'my password',
        scopes = scopesList
    )

#If there is an access token in the result, show it
if "access_token" in result:
    print(result['access_token'])
#Otherwise, print the error
    print(result.get('error'))
    print(result.get('error_description'))
    print(result.get('correlation_id'))
Bill
  • 11
  • 1