Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
jmia
New Member

REST API - Refresh User Metadata

Hello,

 

I am working on an AngularJS SPA that uses Azure AD authentication and integrates with Power BI to display reports and dashboards via the Power BI REST API. I am using ADAL.js for the authentication.

 

I can communicate with the Power BI API just fine, and am listing all workspaces the user has access to along with the all the dashboards and reports within those workspaces. This all works and they can select the report or dasbhoard and view it.

 

The problem I am having is that when a new workspace is shared with a user, it does not come back from the https://api.powerbi.com/v1.0/myorg/groups request until the user manually logs into https://app.powerbi.com. If they then come back to my app and make the call again, the new workspace shows up.

 

I can see that https://app.powerbi.com is making a call to https://wabi-us-east2-redirect.analysis.windows.net/powerbi/metadata/refreshusermetadata. I was able to make this call from Fiddler using the same token that app.powerbi.com uses and see the new workspace show up in my app.

 

My problem is that I can not get my app to make this call. Either I cannot figure out what the right resource is to specify in the endpoints configuration of ADAL.js, or it just won't work with the token that my app has. I see nothing in the Power BI REST API documentation that would be a similar operation.

 

Ulitimately, I need a way for my app to be sure it has all of the latest information without the user having to jump off to the Power BI site. Any help would be greatly appreciated.

 

Thanks!

6 REPLIES 6
JavierRP
Frequent Visitor

Hi @jmia

 

I am developing an app over Angular with power bi embed and I am also using the adal.js library for the authentication.

 

I am having some issues with the embedding, every time that I try to embed something I am retrieving the 403 (Forbidden) error

 

I have checked the configuration of the AAD and is the correct because I am able to generate the correct token using the .NET libraries and use it for embed reports with the power BI JS Library

 

I could be great if you can guide me with this error.

 

This is the configuration for the adal.js 

 

adalConfig: {
    instance: "https://login.microsoftonline.com/",
    tenant: 'XXXXXXXXXXXXXXXXXX',
    clientId: 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
    loginResource:  "https://analysis.windows.net/powerbi/api",
    postLogoutRedirectUri: 'http://localhost:4200/logout',
  },  

 

And this is how I am using the token for embed the reports.

import { Injectable } from '@angular/core';
import { Component, OnInit, Inject, ViewChild, ElementRef, EventEmitter, Output } from '@angular/core';
import { service as PBIService, IEmbedConfiguration, Embed, models } from 'powerbi-client';
import { Adal4Service } from 'adal-angular4';

@Injectable()
export class EmbedingReports {
    component: Embed;
    @Output() embedded: EventEmitter<number> = new EventEmitter<number>();

    constructor (private adalService: Adal4Service, @Inject('PowerBIService') public powerBIService: PBIService.Service) {}

    public embedReport(groupId:string, reportId:string, powerbiFrame: ElementRef) {
        var tokenType  = models.TokenType.Aad;
        var embedUrl  = `https://app.powerbi.com/reportEmbed?reportId=${reportId}&groupId=${groupId}`;
             
        var accessToken = this.adalService.userInfo.token;
        var id = reportId;
        var type = 'report';
        let config: IEmbedConfiguration = {
            accessToken,
            tokenType,
            embedUrl,
            type,
            id
        }
      
        if (this.validateOptions(accessToken, embedUrl)) {
            this.embed(powerbiFrame.nativeElement, config);
        }
    }

    public embedDashboard(htmlElement, groupId:string, dashboardId:string, powerbiFrame: ElementRef){
        var tokenType  = models.TokenType.Aad;
        var embedUrl  = `https://app.powerbi.com/dashboardEmbed?dashboardId=${dashboardId}&groupId=${groupId}`;
        var accessToken = this.token;
        var id = dashboardId;
        var type = "dashboard";
        let config: IEmbedConfiguration = {
            accessToken,
            tokenType,
            embedUrl,
            type,
            id
        }
      
        if (this.validateOptions(accessToken, embedUrl)) {
        this.embed(powerbiFrame.nativeElement, config);
        }
    }


    private embed(element: HTMLElement, config: IEmbedConfiguration) {
        this.component = this.powerBIService.embed(element, config);
        this.embedded.emit((this.component as any));
      }
    
    
    private validateOptions(accessToken: string, embedUrl: string): boolean {
        if (!(typeof embedUrl === 'string' && embedUrl.length > 0)
            || !(typeof accessToken === 'string' && accessToken.length > 0)
        ) {
            return false;
        }
        return true;
    }
}

Thanks in advance,

Javier

@JavierRP

 

Ultimately to get around the 403 issues I was having with the Power BI API I had to add the following to my "endpoints" configuration for ADAL.js:

 

endpoints: {
'https://api.powerbi.com': 'https://analysis.windows.net/powerbi/api',
},

 

Also since using ADAL.js does not support interactive user prompts for permissions, after I set up the permissions for Power BI in the Azure AD App Registration, I had to click Grant Permissions to grant those permissions to the app for all users.

 

Also I had to set my IFrame up like below so that when it had fully loaded the URL that the URL returned from the /myorg/groups/:groupId/reports or /myorg/groups/:groupId/dashboards API call, it would set the token. "controller.selectedReport" was the embed URL returned from the API call and "controller.type" was either "Report" or "Dashboard"

 

<iframe id="report" ng-src="{{controller.selectedReport}}" onLoad="iframeLoaded();" frameborder="0"  style="height:{{controller.screenHeight}}px; width:100%;"></iframe>

 

window.iframeLoaded = function () {
var iframe = document.getElementById("report");
var token = adalService.getCachedToken("https://analysis.windows.net/powerbi/api");
iframe.contentWindow.postMessage(JSON.stringify({ action: "load" + controller.type, accessToken: token }), "*");
};

Glad you got this working!

 

FYI there is some documentation here describing the requirement for Azure permissions to the app registration for the sample:

 

https://docs.microsoft.com/en-us/power-bi/developer/register-app

 

Jon

Eric_Zhang
Employee
Employee

@jmia

Thanks for your reporting. Based on my test, the Power BI groups API indeed works as your description, the API won't return the group until the refreshusermetadata API is called. My understanding is that this is most probably by design.

 

Since the group in Power BI is actually the O365 group, as a workaround, instead of using Power BI REST API, you could try to call the GRAPH group API to read  the groups member information. The list group member API returns group members immediately when I adding a member to one group.

Thanks for the suggestion, that is an interesting idea. If I do that, is there an easy way to tell which groups coming back are associated with Power BI Workspaces? I'll look into it.


@jmia wrote:

Thanks for the suggestion, that is an interesting idea. If I do that, is there an easy way to tell which groups coming back are associated with Power BI Workspaces? I'll look into it.


@jmia

You could try to call the GROUP API and filter O365 groups owned/created by Power BI users in that tenant.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.