arsh
arsh

Reputation: 11

Power BI Rest API getting unauthorized error, even though my application have all the permissions (non-admin) - Getting access token but can't use it

I am pretty new using APIs but i wanted to capture a couple of information regarding my dataset. I created an application in azure active directory and added bunch Power-Bi API permission (read.all). I am a non-admin, so our admin granted consent to all the APIs i requested.

I am using this C# script to get the access token and capture refresh time of my report. However even though i can get the access token, i still receive unauthorized error.

using Microsoft.PowerBI.Api;
using Microsoft.PowerBI.Api.Models;
using Microsoft.Identity.Client;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Rest;
using System.Collections.Generic;

class Program
{
    static async Task Main(string[] args)
    {
        // Azure AD app credentials
        string clientId = "";
        string tenantId = "";
        string workspaceIdString = "";
        Guid workspaceId;
        if (!Guid.TryParse(workspaceIdString, out workspaceId))
        {
            Console.WriteLine("Invalid workspace ID format.");
            return;
        }
        Console.WriteLine("1");

        string datasetId = "";
        var scopes = new[] { "https://analysis.windows.net/powerbi/api/Dataset.Read.All" };
        string clientSecret = "";

        Console.WriteLine("2");
        // access token
        var accessToken = await GetAccessTokenAsync(clientId, clientSecret,tenantId);

        Console.WriteLine($"{accessToken}");

        // Create a Power BI client
        var client = new PowerBIClient(new Uri("https://api.powerbi.com"), new TokenCredentials(accessToken, "Bearer"));

        // Get refresh history
        var refreshes = await client.Datasets.GetRefreshHistoryInGroupAsync(workspaceId, datasetId);

        // Display refresh history
        foreach (var refresh in refreshes.Value)
        {
            Console.WriteLine($"Refresh ID: {refresh.RequestId}");
            Console.WriteLine($"Start Time: {refresh.StartTime}");
            Console.WriteLine($"End Time: {refresh.EndTime}");
            Console.WriteLine($"Status: {refresh.Status}");
            Console.WriteLine();
        }
    }



    static async Task<string> GetAccessTokenAsync(string clientId, string clientSecret, string tenantId)
    {
        var app = ConfidentialClientApplicationBuilder.Create(clientId)
            .WithClientSecret(clientSecret)
            .WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
            .Build();

        var scopes = new[] { "https://analysis.windows.net/powerbi/api/.default" };

        var accounts = await app.GetAccountsAsync();

        var firstAccount = accounts.FirstOrDefault();

        AuthenticationResult authResult;
        try
        {
            if (firstAccount != null)
            {
                authResult = await app.AcquireTokenSilent(scopes, firstAccount).ExecuteAsync();
            }
            else
            {
                authResult = await app.AcquireTokenForClient(scopes).ExecuteAsync();
            }
        }
        catch (MsalUiRequiredException)
        {
            // Handle the exception appropriately for your scenario
            throw;
        }

        return authResult.AccessToken;
    }



}

Also, when i use actual singing in method instead of access token authorization method, i can get refresh time.

Is there any setting that i have change? or does it have to do with me being non admin? Honestly not sure what's going on.

I looked around, and used the manual signing in process, and the script worked fine. But now that i added access token part, i am getting "unauthorized" error. I should mention that i am getting the access token, so there is no problem with my client id, secret and tenant id.

Upvotes: 0

Views: 5268

Answers (1)

Rukmini
Rukmini

Reputation: 16054

I created an Azure AD Application and granted API permissions like below:

enter image description here

Now, created Azure Security Group and added the above Service Principal as a member:

enter image description here

Make sure to enable Allow service principals to use read-only admin APIs add the security group like below:

enter image description here

The above settings will take around 15mins to reflect.

I generated the access token via Postman using Client Credential flow:

https://login.microsoftonline.com/TenantID/oauth2/v2.0/token

client_id:clientID
client_secret:ClientSecret
grant_type:client_credentials
scope:https://analysis.windows.net/powerbi/api/.default

enter image description here

The error 401 Unauthorized usually occurs if the access token doesn't have required permissions to perform the action.

To resolve the error, check the below:

  • Make sure you have added the Azure AD Group in the Power BI portal by enabling Allow service principals to use read-only admin APIs option.
  • In your code try passing scope as var scopes = new[] { "https://analysis.windows.net/powerbi/api/.default" };.
  • Make sure that API permissions are granted Admin consent by the Global Admin.
  • Ensure that the Azure AD Application and Dataset are in the same tenant.
  • If still the issue persists, try to generate the access token via Authorization Code Flow as Dataset.Read.All is a delegated API permission.

Upvotes: 1

Related Questions