Irfan Harun
Irfan Harun

Reputation: 1059

Power BI embed error 403 forbidden error from server

I'm following the steps mentioned in the power BI community here and testing it out in Postman and have completed first 4 steps. However on testing the embed code in Microsoft Power BI Embedded Playground, i keep getting following error :

{
  "message": "LoadReportFailed",
  "detailedMessage": "Fail to initialize - Could not resolve cluster",
  "errorCode": "403",
  "level": 6,
  "technicalDetails": {
    "requestId": "57679585-022b-4871-ae6d-bb722d4a07cc"
  }
}

Also, when trying the alternative, HTML setup provided in STEP 5, i again keep getting 403 error stating : "GET https://wabi-india-west-redirect.analysis.windows.net/powerbi/globalservice/v201606/clusterdetails 403 (Forbidden)"

Please help. I've been trying to get this thing to work for over a week now.

Upvotes: 1

Views: 15610

Answers (3)

Muni Chittem
Muni Chittem

Reputation: 1126

This issues I fixed finally using below steps.

For embed the power BI reports in front end (angular/ JS) you have to generate 2 different tokens (for app-only scenario).

  1. Access token using master account details /service principal account ( this is used to connect with power BI server)
  2. Embed token (can be generated using access token & .NET Power BI rest API's).

Step1 : Access Token generation

PBIClientId": "xxxxxx-xxx-xxxx-xxxx-xxxxxxxxx",
    "PBIClientSecret": "<client secret>",
    "PBIApiUrl": "https://api.powerbi.com/",
    "ResourceUrl": "https://analysis.windows.net/powerbi/api",
    "AuthorityUrl": "https://login.windows.net/common/",
    "TenantId": "<TenantId>",

private async Task<string> GeneratePowerBIAccessToken()
    {
        var tenantSpecificURL = authorityUrl.Replace("common", tenantId);
        var authenticationContext = new AuthenticationContext(tenantSpecificURL);

        // Authentication using app credentials
        var credential = new ClientCredential(clientId, clientSecret);
        AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, credential);
        return authenticationResult.AccessToken;
    }

Step2: Get Power BI Report Embed URL

Pass access token which is generated in step1, groupId and reportId you get from power BI portal url.

 private async Task<EmbedModel> GetEmbedReportModel(string groupId, string reportId, string accessToken)
    {
        string restUrl = "https://api.powerbi.com/v1.0/myorg/groups/" + groupId+"/reports";

        // add JSON to HttpContent object and configure content type
        var method = new HttpMethod("GET");
        var request = new HttpRequestMessage(method, restUrl);

        using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);

            // send POST request to Power BI service 
            var jsonResult = await client.SendAsync(request).Result.Content.ReadAsStringAsync();
            var reportObject = JsonConvert.DeserializeObject<ReportObjects>(jsonResult);
            var report = reportObject.value.Where(r => r.id == reportId).FirstOrDefault();
            return new EmbedModel { Id = report.id, EmbedUrl = report.embedUrl, Name = report.name };
        }
    }

the response you will get here is 
    {
  "value": [
    {
      "datasetId": "xxxxxx-abcasdasd-dasda-4weas",
      "id": "3asder78-asds-4d73-1232-5345dfsdfs",
      "name": "SalesMarketing",
      "webUrl": "https://app.powerbi.com/groups/xxx-xxxxx-xxx-xxxxxx-xxxxx/reports/xxxxxx-xxxx-xxx-xxxx-xxxxxxxx",
      "embedUrl": "https://app.powerbi.com/reportEmbed?reportId=xxxxxx-xxxx-xxxx-xxxx-xxxxxx&groupId=aadasda21-xxcx-xx-xx-xxxxxx"
    }
  ]
}

step 3: Call generate embed token API

 private async  Task<EmbedToken> GenerateEmbedToken(string groupId, string reportId,string accessToken)
    {
        string apiURL = "https://api.powerbi.com/v1.0/myorg/groups/"+ groupId + "/reports/"+ reportId +"/GenerateToken";
        string requestBody = @"{ ""accessLevel"": ""View""}";
        HttpContent postRequestBody = new StringContent(requestBody);
        postRequestBody.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");

        // prepare PATCH request
        var method = new HttpMethod("POST");
        var request = new HttpRequestMessage(method, apiURL);
        request.Content = postRequestBody;

        using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);

            // send POST request to Power BI service 
            var jsonResult = await client.SendAsync(request).Result.Content.ReadAsStringAsync();
            EmbedToken embedToken = JsonConvert.DeserializeObject<EmbedToken>(jsonResult);

            return embedToken;
        }
    }

Step 4: Use embed token and embed url in front end app

<html>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
  <script src="powerbi.min.js" type="text/javascript"> </script>
  <script type="text/javascript">
           window.onload = function () {
           var models = window['powerbi-client'].models;
          var embedConfiguration = {
               type: 'report',
			   id:'537887ee-7c7c-43c6-850b-9293f60aa3f3',
               accessToken: 'H4sIAAAAAAAEAB3Tt66EV.....phVP_a_5F15fA_FCBQAA',
               embedUrl: 'https://app.powerbi.com/reportEmbed?reportId=2376660ee-1c2c-16c6-980b-923260aa3f3&amp;groupId=2adeaaa-xxxx-xxxx-xxxx-8d13b04c6e0e&amp;w=2&amp;config=eyJjbHVzdGVyV.....',
               permissions: models.Permissions.All,
               tokenType: models.TokenType.Embed,
               viewMode:models.ViewMode.View,
           };

           var $reportContainer = $('#dashboardContainer');
           var report = powerbi.embed($reportContainer.get(0), embedConfiguration);

       }
   </script>
   <div id="dashboardContainer"></div>
</html>

Change all values before you run this.

Upvotes: 2

Irfan Harun
Irfan Harun

Reputation: 1059

It turns out that though i had workspace ID, client ID, report ID and though i was making proper calls to the API, the error in the fifth step was because i was a member of the the workspace where my reports were.

For API to work, you need to be the admin of the workspace from which you are trying to get the reports

Upvotes: 2

Prathako
Prathako

Reputation: 91

Please make sure you are sending correct Token in the authorization header. Make sure you use "Bearer " as Authorization header.

Also, make sure your user has all required permissions.

Upvotes: 1

Related Questions