5

We have developed a Power BI report and we have a requirement to embed the Power BI report inside an Angular Application. The Angular Application works with OAuth authentication. We have seen how to embed the Power BI Report (as mentioned in the link - Embedding for Customers - https://learn.microsoft.com/en-us/power-bi/developer/embedding#embedding-for-your-customers)

We also have a requirement to do a fine grained authorization within the Power BI report. Is it possible to filter the data based on the user logged in to the Angular UI Application?

Andrey Nikolov
  • 12,967
  • 3
  • 20
  • 32
Silly John
  • 1,584
  • 2
  • 16
  • 34

3 Answers3

2

Yes, it's possible, I've used Ngx-power-bi. Try this:

private powerBiService: NgxPowerBiService;
private pbiContainerElement: HTMLElement;

private reportId = "YOUR REPORT ID";
private groupId = "YOUR GROUP ID";
private filterPaneEnabled= false;
private navContentPaneEnabled= true;
    
constructor(private authService: AuthService,private dashboardService:DashboardService) {
this.powerBiService = new NgxPowerBiService();
}

ngOnInit() {

//Get the token from backend, You may use switchMap or flatMap 
//to get the user data (table, column, value etc)

this.dashboardService.getAccessToken().pipe(untilDestroyed(this)).subscribe(token=>{
    const config = {
        type: 'report',
        id: this.reportId,
        embedUrl:
          'https://app.powerbi.com/reportEmbed?' +
          'reportId='+this.reportId +
          '&groupId='+ this.groupId,
        accessToken:token.accessToken,
        settings: {
          filterPaneEnabled: this.filterPaneEnabled,
          navContentPaneEnabled: this.navContentPaneEnabled
        },
        filters:[{
            $schema: "http://powerbi.com/product/schema",
            filterType:1,
            target: {
              table: "Master", // filter table
              column: "companyId" // filter column
            },
            operator: "In",
            values: [101]   // value that you need to filter

          }]
      };
    this.pbiContainerElement = <HTMLElement>(document.getElementById('pbi-container'));
    this.powerBiService.embed(this.pbiContainerElement, config);
})

   
   
halfer
  • 19,824
  • 17
  • 99
  • 186
varman
  • 8,704
  • 5
  • 19
  • 53
  • can you help me to understand how to access powerBI if it has instance in Azure portal. ? as of now PowerBi instance only created in Azure where i can get cliendTD there. and then i'll be creating dashboard and reports in powerBI.. how embedd the powerbi dashboards and reports in my Angular app. – Mr. Learner Jun 01 '21 at 10:02
  • i've gone through you comments it's understandable only. but the only thing i confused here is how to pass access my powerBI dashboard via Azure portal. if possible kindly share me some snippet or stackblitz demo – Mr. Learner Jun 01 '21 at 10:04
  • @Mr.Learner It's been a while ago and I'm not touch in that. But I will try my best – varman Jun 01 '21 at 14:37
  • thank you so much for your response. spending more time on this and i'm still trying my level best to understand and implement this but couldn't make it, though having proper MS documentation. So pls share your knowledge – Mr. Learner Jun 02 '21 at 04:16
1

You can achieve this in two ways - define filters when embedding the report or with Row-Level Security.

When embedding Power BI elements, you are initializing a configuration. One of the properties of this object are the filters to be pre-applied on the report, when loaded. Currently these are the supported filter types:

export enum FilterType {
  Advanced = 0,
  Basic = 1,
  Unknown = 2,
  IncludeExclude = 3,
  RelativeDate = 4,
  TopN = 5,
  Tuple = 6
}

These types corresponds to the filters, that you can apply in the report when shown in a browser or in Power BI Desktop. For more information what properties each filter type has and how to use it, see Filters page in the documentation, but for example a basic filter needs to define the table and column, on which the filter will be applied, comparison operator, and of course values, e.g.:

const basicFilter: pbi.models.IBasicFilter = {
  $schema: "http://powerbi.com/product/schema#basic",
  target: {
    table: "Store",
    column: "Count"
  },
  operator: "In",
  values: [1,2,3,4],
  filterType: 1 // pbi.models.FilterType.BasicFilter
}

or

const basicFilter = {
  $schema: "http://powerbi.com/product/schema#basic",
  target: {
    table: "Store",
    column: "Count"
  },
  operator: "In",
  values: [1,2,3,4],
  filterType: 1 // pbi.models.FilterType.BasicFilter
}

Then set this filter in the configuration prior embedding:

var config = {
    type: embedType,
    accessToken: accessToken,
    tokenType: tokenType,
    embedUrl: embedUrl,
    id: embedId,
    dashboardId: dashboardId,
    permissions: permissions,
    settings: {
        filterPaneEnabled: false,
        navContentPaneEnabled: true
    },
    filters: [basicFilter]
};

Note, that in this case you should hide the filter pane, by setting filterPaneEnabled: false, otherwise the user will see the pre-applied filter in the filters pane and will be able to change it or remove it! But if you hide the filters pane, this will limit the users options to analyze the data by only using the slisers and other options provided in the report itself. So using RLS may be a better idea, but it requires a dedicated capacity for your workspace (i.e. buying Power BI Premium or Power BI Embedded).

To use RLS you must define one or more roles in your report. For each role a DAX expression will be defined to filter the data. Then for each of your users, you can decide which role or roles to give and the report will show only the data accessible to these roles. Then use the AAD token that you get, to call GenerateTokenInGroup REST API and pass the roles that you want your user to have in the request body:

{
  "accessLevel": "View",
  "identities": [
    {
      "username": "john@contoso.com",
      "roles": [
        "sales",
        "marketing"
      ],
      "datasets": [
        "cfafbeb1-8037-4d0c-896e-a46fb27ff229"
      ]
    }
  ]
}

Then use the above acquired token to embed the report and don't forget to change the value of tokenType property in the configuration to be 1 (embed) instead of 0 (AAD), if needed.

This way you can leave the filters pane visible, because the security policies will be applied under the hood by the engine.

Andrey Nikolov
  • 12,967
  • 3
  • 20
  • 32
-1

Here is a link you can use as a reference https://www.npmjs.com/package/ngx-powerbi Angular can easily pass embedded parameters if you use method type 3 for basic filters. for more information checkout the power bi official website

<div id="pbi-container"></div>


const config = {
        type: 'report',
        tokenType: models.TokenType.Embed,
        id: reportConfigResponse.EmbedReport.ReportId,
        embedUrl: reportConfigResponse.EmbedReport.EmbedUrl,
        accessToken: reportConfigResponse.EmbedToken.Token,
        settings: {
          filterPaneEnabled: false,
          navContentPaneEnabled: true
        },
        filters: [{
          $schema: "http://powerbi.com/product/schema#basic",
          target: {
            table: "vw_Customers",
            column: "ID"
          },
          operator: "In",
          values: [1],
          filterType: models.FilterType.Basic
        }]
      };

  this.pbiContainerElement = <HTMLElement>(document.getElementById('pbi-container'));
  this.powerBiService.embed(this.pbiContainerElement, config);
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 29 '23 at 08:24