Reputation: 11
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
Reputation: 16054
I created an Azure AD Application and granted API permissions like below:
Now, created Azure Security Group and added the above Service Principal as a member:
Make sure to enable Allow service principals to use read-only admin APIs
add the security group like below:
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
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:
Allow service principals to use read-only admin APIs
option. var scopes = new[] { "https://analysis.windows.net/powerbi/api/.default" };
.Dataset.Read.All
is a delegated API permission.Upvotes: 1