Receiving a 'Forbidden (403)' when connecting to Power BI API

14.3k views Asked by At

We've been trying to follow this Power BI article so that we can embed reports/dashboards in our SaaS product. Specifically, we're stuck at Step 3, 'Create the Embed Token.'

We're able to obtain an bearer token just fine but when the request to retrieve the reports is ultimately submitted to the API we receive:Operation returned an invalid status code 'Forbidden'

    private static string clientId = "...";
    private static string secretKey = "...";
    private static string groupId = "...";

    static void Main(string[] args)
    {
        string resourceUri = "https://analysis.windows.net/powerbi/api";
        string authorityUri = "https://login.windows.net/common/oauth2/authorize";

        ClientCredential credential = new ClientCredential(clientId, secretKey);
        AuthenticationContext authContext = new AuthenticationContext(authorityUri);

        var token = authContext.AcquireTokenAsync(resourceUri, credential).Result.AccessToken;

        var tokenCredentials = new TokenCredentials(token, "Bearer");

        using (var client = new PowerBIClient(new Uri("https://api.powerbi.com/"), tokenCredentials))
        {
            var reports = client.Reports.GetReportsInGroupWithHttpMessagesAsync(groupId);

            // !!! - Here's where the exception is thrown
            // !!! -- Operation returned an invalid status code 'Forbidden'
            var report = reports.Result.Body;
        }
    }

Here's what we've tried:

  • The required permissions have been granted (we've checked off all to ensure we're not missing anything). This includes both Windows Azure Active Directory/Power BI Service.
  • We've confirmed that the client ID, secret key and group id are correct.
  • The Power BI work-space is private, but we've tried making a public one to be sure it doesn't matter.
  • Finally, the token we receive via code matches the token on powerbi.com.
5

There are 5 answers

5
Nan Yu On BEST ANSWER

You are using client credential flow to acquire token for Power BI API . Currently , Power BI REST API only supports delegated permissions but does not support any application permissions . So your access token get insufficient access. To use Power BI, authentication needs to be based on a particular user. Related thread here and here are for your reference .

According to your document ,the scenario is app owns access to the data. Users will not necessarily be Power BI users and the application controls authentication and access for the end users. Then you can use resource owner flow to acquiring token .

A sample of this is available within Controllers\HomeController.cs of the App Owns Data sample.

From the code sample , it is acquring token using a user password credential ,not application's credential :

            // Create a user password cradentials.
            var credential = new UserPasswordCredential(Username, Password);

            // Authenticate using created credentials
            var authenticationContext = new AuthenticationContext(AuthorityUrl);
            var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential);

Please refer to Authenticate users and get an Azure AD access token for your Power BI app and check the Access token for non-Power BI users (app owns data) section .

0
Jayendran On

This is because you are trying to call some Reports/Dashboards that are in My Workspace using the SPN authentication. Currently this is the known limitation for SPN

Reference

enter image description here

0
dev.bv On

We have found that the group (App Workspace) needs to be owned by the same user who authenticates with Azure. This user also needs to be listed as the owner on the Azure App that you register.Once you revised permissions. Don't forget to republish powerbi report then only it reflects changes.

0
Michael Blake On

The best way to get the real exceptions from Power BI is to add a DelegatingHandler and look at the headers / body of the message.

https://github.com/Microsoft/PowerBI-CSharp/compare/master...mikeblakeuk:feature/exceptionHandler

0
Jorge Valvert On

Certain Power Bi Apis can only be accessed by using a profile Id it must be sent over the HTTP headers (X-PowerBI-Profile-Id)

The profile api can be invoked using the token associated to the service principal this way:

POST https://api.powerbi.com/v1.0/myorg/profiles HTTP/1.1
Authorization: Bearer eyJ0eXAiOiJK…UUPA
Content-Type: application/json; charset=utf-8

{"displayName":"ContosoProfile"}

It will return the profile id:

{
"@odata.context": "http://wabi-west-us- 
 redirect.analysis.windows.net/v1.0/myorg/$metadata#profiles",
"value": [
    {
        "id": "a4df5235-6f18-4141-9e99-0c3512f41306",
        "displayName": "ContosoProfile"
    }
 ]
}

After that, consume the power bi api sending the profile id into the http header X-PowerBI-Profile-Id along with the Authorization header, for instance to create a new workspace:

POST https://api.powerbi.com/v1.0/myorg/groups HTTP/1.1
Authorization: Bearer eyJ0eXA…ZUiIsg
Content-Type: application/json; charset=utf-8
X-PowerBI-Profile-Id: a4df5235-6f18-4141-9e99-0c3512f41306

{
 "name": "ContosoWorkspace"
}

Reference: https://learn.microsoft.com/en-us/power-bi/developer/embedded/embed-multi-tenancy