1
votes

I would try the Power BI API.

So I start by getting Embed Token ( I'm using application owns data scenario ).

1.access Token

var options = {
    'method': 'POST',
    'url': `https://login.microsoftonline.com/${process.env.TENANT_ID}/oauth2/token`,
    'headers': {
        'Content-Type': 'multipart/form-data'
    },
    formData: {
        'grant_type': process.env.GRANT_TYPE,
        'client_id': process.env.CLIENT_ID,
        'client_secret': process.env.CLIENT_SECRET,
        'resource': process.env.RESSOURCE,
        'Scope': process.env.SCOPE
    }
};

// get Access token from AAD to retrieve Embed Token in PBI API
let response;
try {
    response = await new Promise((resolve, reject) => {
        request(options, (error, response, data) => {
            if (error) reject(error)
            else resolve(data)
        })
    })
}
catch (error) {
    context.error(error)
}

2.Fetch embed Token (Docs)

var data = '{accessLevel:"View"}';

var config = {
    method: 'post',
    url: `https://api.powerbi.com/v1.0/myorg/groups/${process.env.GROUP_ID}/dashboards/${process.env.DASHBOARD_ID}/GenerateToken`,
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${JSON.parse(response).access_token}`
    },
    data: data
};

const embedtoken = await axios(config)

context.res = {
    // status: 200, /* Defaults to 200 */
    body: embedtoken.data
};

3. I have delegated permissions on azure

enter image description here

I'm getting an embed token.

4. fetch dashboard infos

I'm using postman to fetch dashboard infos from the same group id and dashboard id that I mentioned in the api to get embed token

( I add that token in authorization section )

The problem is that I'm getting 403 Forbidden error. enter image description here

PS: In this post some limitations of service principal method are mentioned . is it the source of my problem ? Am I obliged to use master user method ?

enter image description here

1
In the title you said it is My workspace, but in the post you are talking about groups, so it is A workspace, right? Does the service principal has rights on it? For the test, change tokenType in the embedded configuration to AAD and use the first token to authorize the embedding. Can you get the list of dashboards or reports using it?Andrey Nikolov
For testing I would try with dashboards then reports , Should I use access token or embed token ?infodev
Test with the access token to prove that the service principal is set correctly.Andrey Nikolov
ok but to understand , access token is it only to get embed token using service principale ?infodev
You can perfectly embed reports and dashboards using the AAD access token. However, this is something visible on the client side (it is JavaScript code running in the browser), so it is a security risk to expose it like that - it can be used to call the API and can do you harm. That why on the server side it is used to generate an embed token, which has shorter live, it is valid only for this particular report/dashboard and can't be used to call the API.Andrey Nikolov

1 Answers

1
votes

You have a misunderstanding of the usage of Embed Token. It cannot be used to call https://api.powerbi.com/v1.0/myorg/groups/{group id}/dashboards/{dashboard id}/ directly. AAD token is needed here.

To use an Embed Token, you should call the Embed URL with it.

The format of Embed URL is like:

https://app.powerbi.com/reportEmbed?reportId=f6bfd646-b718-44dc-a378-b73e6b528204&groupId=be8908da-da25-452e-b220-163f52476cdd&config=eyJjbHVzdGVyVXJsIjoiaHR0cHM6Ly9XQUJJLVVTLU5PUlRILUNFTlRSQUwtcmVkaXJlY3QuYW5hbHlzaXMud2luZG93cy5uZXQiLCJlbWJlZEZlYXR1cmVzIjp7Im1vZGVybkVtYmVkIjp0cnVlfX0%3d

An .net example:

// You need to provide the workspaceId where the dashboard resides.
ODataResponseListReport reports = await client.Reports.GetReportsInGroupAsync(workspaceId);

// Get the first report in the group.
Report report = reports.Value.FirstOrDefault();

// Generate Embed Token.
var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
EmbedToken tokenResponse = client.Reports.GenerateTokenInGroup(workspaceId, report.Id, generateTokenRequestParameters);

// Generate Embed Configuration.
var embedConfig = new EmbedConfig()
{
    EmbedToken = tokenResponse,
    EmbedUrl = report.EmbedUrl,
    Id = report.Id
};

Then you can call the EmbedUrl with EmbedToken.

Reference here.