6
votes

I am trying to get a sample power BI embed (user owns data mode) working in an angular5 application. Below is what I have done so far:

  1. Installed powerbi & powerbi client npm packages.
  2. I have created an AAD app and given all access to powerbi apis.

Below is the code of my component:

import { Component, OnInit } from '@angular/core';
import * as pbicli from 'powerbi-client';
import {AuthenticationService} from '../authentication';
@Component({
  selector: 'app-powerbi-qna',
  templateUrl: './powerbi-qna.component.html',
  styleUrls: ['./powerbi-qna.component.scss']
})
export class PowerbiQnaComponent implements OnInit {
embedToken: string;
  constructor(private authSvc: AuthenticationService) { }

  ngOnInit() {
    // get embed tokens

    this.loadDashboard();
  }
loadDashboard() {
// Read embed application token from textbox
this.displayDashboard(this.authSvc.getCachedToken());
}
displayDashboard(token: string) {
const embedUrl = 'https://app.powerbi.com/reportEmbed?reportId=<reportid>';
const embedReportId = '<reportid>';
const config = {
    type: 'report',
    tokenType: 0,
    accessToken: token,
    embedUrl: embedUrl,
    id: embedReportId,
    permissions: 7,
    settings: {
    }
};
// Get a reference to the embedded report HTML element
const embedContainer = <HTMLElement>document.getElementById('powerBiEmbed');
const powerbi = new pbicli.service.Service(pbicli.factories.hpmFactory, pbicli.factories.wpmpFactory, pbicli.factories.routerFactory);
// Embed the report and display it within the div container.
const report = powerbi.embed(embedContainer, config);
// Report.off removes a given event handler if it exists.
report.off('loaded');
// Report.on will add an event handler which prints to Log window.
report.on('loaded', function() {
  console.log('Loaded');
});
report.on('error', function(event) {
  console.log(event.detail);
    report.off('error');
});
report.off('saved');
report.on('saved', function(event) {
    console.log(event.detail);
 });
}
}

But things are not working and I get below exception in console: GET https://wabi-west-europe-redirect.analysis.windows.net/metadata/cluster 403 (Forbidden)

I am trying to access the powerbi using the loggedin user's license (User owns data) What am I missing here?

8
can you perhaps share the content & full response (w/ headers) for that 403? - RBreuer
did you found the solution? if you have the solution can you please post the entire steps to integrate PowerBI in angular, it would be helpful to us? - Krishnan

8 Answers

3
votes

I had the same problem. For me the solution was that I was using the wrong tokenType. https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embedding-Basics states that for "Application owned" data Embed should be used.

From https://github.com/Microsoft/powerbi-models/blob/baaaf184d4966b09094a2539a538bf10c6cb69c4/src/models.ts:

export enum TokenType {
    Aad,
    Embed
}
1
votes

Please refer my article which contains the steps to embed powerbi reports in angular application. This article contains the steps to deploy the report under a workspace, grant the required permissions in Azure AD, also granting the admin-consent related to PowerBI embedded etc. https://snkrishnan1.wordpress.com/2018/06/25/embed-power-bi-reports-in-angular-5-application/

0
votes

I had similar problems. Hopefully this helps.

Some PowerBI resources have group ids and some don't. If you omit the group id then you'll get a 403 Forbidden.

My embedUrl looks like this:

embedUrl: `https://app.powerbi.com/${PbiType}Embed?${PbiType}Id=${ResourceId}` + (GroupId ? `&groupId=${GroupId}` : ''),

0
votes

@Patrick P. : Your Authorization header value of 'EmbedToken ey....' suggests you're accidentally using tokenType: Embed (1) in your embed config.

Rule of thumb: ey prefix of the token usually suggests AAD TokenType (0), H4 prefix suggests EmbedToken (1).

As @Taul answered too, this is usually the problem with wrong tokens. Other options can be wrong groupId & reportId in config.

0
votes

I am running into the same problem. As @RBreuer asked for the full header, here are mine:

Request (as CURL, exported from Chrome)

curl 'https://wabi-west-europe-redirect.analysis.windows.net/metadata/cluster' -H 'Authorization: EmbedToken eyJ0eXAiOiJKV1QiLCJhbGciOiJSU....' -H 'Origin: https://app.powerbi.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9' -H 'RequestId: b6837253-d152-8325-08b9-227c683363d3' -H 'ActivityId: b91d1b42-3d72-4cd2-8094-709af013cf83' -H 'Accept: application/json, text/plain, /' -H 'Referer: https://app.powerbi.com/reportEmbed?reportId=53f75214-7b5f-4264-b7ea-xxxxxxxxxx&groupId=b580bbcc-75ce-4347-bbfd-xxxxxxxxx' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/66.0.3359.181 Chrome/66.0.3359.181 Safari/537.36' -H 'Connection: keep-alive' --compressed

Answer is:

Request URL: https://wabi-west-europe-redirect.analysis.windows.net/metadata/cluster
Request Method: GET
Status Code: 403 Forbidden
Remote Address: 13.95.158.123:443
Referrer Policy: no-referrer-when-downgrade

I am running Angular6 with latest powerbi-client.

I receive the accessToken with adal (python lib) in my backend for a prev. configured Azure Application with native support proxying my pbi-report as described in the PBI-Docs for App Owns Data configuration.

Hope that information help someone to solve the problem or at least point into the right direction ;)

0
votes

Use the following code to embed your PowerBI report into Angular application. It works perfectly for me. You need to fill accessToken, embedUrl, embedReportId.

showReport() {
    // Report's Secured Token
    let accessToken = 'Access Token';
    // Embed URL
    let embedUrl = 'Embed URL';
    // Report ID
    let embedReportId = 'Report ID';
    let config = {
      type: 'report',
      accessToken: accessToken,
      embedUrl: embedUrl,
      id: embedReportId,
      permissions: pbi.models.Permissions.All,
      settings: {
        localeSettings: {
          language: "en",
          formatLocale: "es"
        }
      }
    };
    // Grab the reference to the div HTML element that will host the report.
    let reportContainer = <HTMLElement>document.getElementById('reportContainer');
    // Embed the report and display it within the div container.
    let powerbi = new pbi.service.Service(pbi.factories.hpmFactory, pbi.factories.wpmpFactory, pbi.factories.routerFactory);
    let report = powerbi.embed(reportContainer, config);
    var rep = powerbi.get(reportContainer);

    //Report.off removes a given event handler if it exists.
    report.off("loaded");
    // Report.on will add an event handler which prints to Log window.
    report.on("loaded", function () {
      console.log("Loaded");
    });    
  }
0
votes

You can try this code:

showReports() {
  const config = <IEmbedConfigurationBase><any>{ // add this type of object  <IEmbedConfigurationBase><any>
type: 'report',
uniqueId: 'your-report-id ',
id: 'your-report-id ',
tokenType: 'Embed Token',
settings: {
  navContentPaneEnabled: false,
  filterPaneEnabled: false
},
embedUrl: 'your-embed url',
accessToken: 'your-access-token'
};

 const reportsContainer = <HTMLElement>document.getElementById(
     'reportsContainer'
    );

const powerbi = new pbi.service.Service(
   pbi.factories.hpmFactory,
   pbi.factories.wpmpFactory,
   pbi.factories.routerFactory
 );
const report = powerbi.embed(
  reportsContainer,
  config
);
} 

For more refernces - Interface IEmbedConfigurationBase

Nodejs POC to generate accessToken

-2
votes

power bi service might be not available in some regions .Please check availability of services in your regions.other reason may be you should create native app and then try to embed.