Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.

Reply
uahmed114pbi
Frequent Visitor

Dynamic Token refresh for PBI Admin API calls not being accepted

Hello, 

 

   I have searched through all the related posts in the forums before posting here. I can't seem to figure out what the issue is. I was following this video tutorial to build out an Admin view, as I am the platform owner of PBI at my company (building an admin view in PBI). After much struggling, I was able to return a token, but the weird thing is that it doesn't work. I cannot for the life of me figure out why. What I was initially doing was going to learn.microsoft.com and hitting the "try" button and getting the Bearer token from there. WHenever I do that, it works just fine. But I wanted it to update as needed, so following that video I'm returning a token but it's not accepted. 

 

Here's what I'm doing:  (note: the video used grant_type=password, but that doesnt work for me since we have MFA enabled, so reading through docs I found out that would be an issue. So im using client_credentials instead, which works). 

 

This is the API i'm calling: "https://api.powerbi.com/v1.0/myorg/admin/groups?%24top=100"

 

()=>
let
    //Found in Portal Azure site under App Registration: 
    tenant_id = "***************", //Overview Tab: Directory/Tenant ID
    client_id = "***************", //Overview Tab: Application/Client ID
    client_secret = "****************************", //Certificates & secrets Tab: PowerBI secret Value

    //POST Request
    url = "https://login.microsoftonline.com/"&tenant_id&"/oauth2/v2.0/token",
    body = [
        grant_type = "client_credentials",
        scope = "https://analysis.windows.net/powerbi/api/.default",
        client_id = client_id,
        client_secret=client_secret
    ],

    //Get token
    GetJson =
        Json.Document(
            Web.Contents(
                url, [
                    Headers=[
                        Accept="application/json", 
                        #"Content-Type"="application/x-www-form-urlencoded"
                    ], 
                    Content= Text.ToBinary(Uri.BuildQueryString(body))
                ]
            )
        ),
    access_token = GetJson[access_token]
in
    access_token

This whole thing works fine in Postman and in PBI. I did notice that the token was actually slightly shorter than the ones I pull from learn.microsoft.com. 

All the settings in the app registration are set correctly. Service Principal is enabled in PBI Admin, the app is assigned to the correct group (PBI-Embedded), and that group is allowed in Service Principal settings. I have Tenant.Read.All enabled, all the settings are good from that end too. Any help with this would be great. 

I've seen multiple videos on this, they all are doing what I'm doing but it works for them but not for me. I've read through all the forum posts and its the same. 

1 ACCEPTED SOLUTION
uahmed114pbi
Frequent Visitor

I figured out the solution. For anyone who ever encounters the same issue, I'm laying it out clearly here as it is a little confusing, and the docs aren't clear about this:

 

If your organization has MFA enabled, then you either need to disable MFA or you cannot use your username/password to connect, so the grant_type = password cannot be used in this case. 

If you use grant_type = password and MFA is disabled, then you need to also make sure the app has Tenant.Read.All API permission enabled, to be able to connect. 

If you cannot disable MFA (which was the case for me as our org wouldn't allow that ofcourse), then using the grant_type = client_credentials is the way to go. You'll need to provide the client_id, client_secret, scope and tenant_id. But make sure to REMOVE Tenant.Read.All from the API permissions.

When using service principal, you CANNOT have Tenant.Read.All permissions allowed in the app reg. This was the problem for me. I didn't know about the MFA, so I had Tenant.Read.All permissions allowed but it still didn't work. Then once I tried with grant_type = client_credentials, it still wouldn't work because I needed to remove the Tenant.Read.All permissions for it to work. 

To summarize: 

  • When connecting with grant_type = password, you need to disable MFA and have Tenant.Read.All permissions enabled in the API Permissions (which in my case was not an option).
  • When connecting with grant_type = client_credentials, Tenant.Read.All must be disabled and provide client_id, client_secret, tenant_id and scope. 

 

View solution in original post

3 REPLIES 3
uahmed114pbi
Frequent Visitor

I figured out the solution. For anyone who ever encounters the same issue, I'm laying it out clearly here as it is a little confusing, and the docs aren't clear about this:

 

If your organization has MFA enabled, then you either need to disable MFA or you cannot use your username/password to connect, so the grant_type = password cannot be used in this case. 

If you use grant_type = password and MFA is disabled, then you need to also make sure the app has Tenant.Read.All API permission enabled, to be able to connect. 

If you cannot disable MFA (which was the case for me as our org wouldn't allow that ofcourse), then using the grant_type = client_credentials is the way to go. You'll need to provide the client_id, client_secret, scope and tenant_id. But make sure to REMOVE Tenant.Read.All from the API permissions.

When using service principal, you CANNOT have Tenant.Read.All permissions allowed in the app reg. This was the problem for me. I didn't know about the MFA, so I had Tenant.Read.All permissions allowed but it still didn't work. Then once I tried with grant_type = client_credentials, it still wouldn't work because I needed to remove the Tenant.Read.All permissions for it to work. 

To summarize: 

  • When connecting with grant_type = password, you need to disable MFA and have Tenant.Read.All permissions enabled in the API Permissions (which in my case was not an option).
  • When connecting with grant_type = client_credentials, Tenant.Read.All must be disabled and provide client_id, client_secret, tenant_id and scope. 

 

v-shex-msft
Community Support
Community Support

HI @uahmed114pbi,

I'd like to suggest you take a look at the following blog to know more about 'relative path' or other optional parameters in web contents if it helps:

Using The RelativePath And Query Options With Web Contents in Power query and Power bi M code 

Regards,

Xiaoxin Sheng

Community Support Team _ Xiaoxin
If this post helps, please consider accept as solution to help other members find it more quickly.
uahmed114pbi
Frequent Visitor

Here are the app permissions in Azure portal: 

uahmed114pbi_0-1703285025111.png

 

Helpful resources

Announcements
LearnSurvey

Fabric certifications survey

Certification feedback opportunity for the community.

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.