node.js - Unauthorized to retrieve PowerBI embed token - Stack Overflow

I already have found other similar issues on Stack Overflow, but still have issue to retrieving the emb

I already have found other similar issues on Stack Overflow, but still have issue to retrieving the embed token in Node.js, with the message:

2025-03-07T08:31:35.098660921Z Error: Failed to get embed token: 401 Unauthorized -
2025-03-07T08:31:35.098716024Z     at /app/src/services/PowerBIService.ts:135:13
2025-03-07T08:31:35.098722924Z     at Generator.next (<anonymous>)
2025-03-07T08:31:35.098728225Z     at fulfilled (/app/src/services/PowerBIService.ts:5:58)
2025-03-07T08:31:35.098733225Z     at processTicksAndRejections (node:internal/process/task_queues:95:5)

I already:

  • Created a Workspace in PowerBI
  • Assigned to the Workspace all the necessary API Authorizations
  • Created a new App in Azure
  • Given the PowerBI Authorization on the Azure App
  • Created a Security Group with the App (service principal)
  • Assigned as Admin role that Security Group to the PowerBI's Workspace
  • Enabled all the necessary stuffs on Admin Portal of PowerBI, Tenant Settings

The method I Created is this, I use ClientSecretCredentials with the Tenant ID, Client ID and Client Secret of the app:

async function getPowerBIEmbedResponse(
  reportId: string,
  datasetId: string,
  groupId: string
): Promise<any> {
  Logger.info("Inside getPowerBIEmbedResponse");

  try {
    const credential = new ClientSecretCredential(
      "bbbb", // Tenant ID
      "aaaa", // App Registration client ID
      "abcd" // Client secret
    );

    const tokenResponse = await credential.getToken(
      "/.default"
    );

    // const tokenResponse = await credential.getToken(
    //   "/.default"
    // );

    if (!tokenResponse || !tokenResponse.token) {
      throw new Error("Failed to retrieve Azure access token.");
    }

    Logger.info("Token obtained successfully");
    const accessToken = tokenResponse.token;

    const url = `.0/my/groups/${groupId}/reports/${reportId}/GenerateToken`;
    // .0/my/GenerateToken

    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify({
        accessLevel: "View",
        datasetId: datasetId,
      }),
    });

    if (!response.ok) {
      const errorText = await response.text();
      Logger.error(`Error response body: ${errorText}`);
      throw new Error(
        `Failed to get embed token: ${response.status} ${response.statusText} - ${errorText}`
      );
    }

    const data = await response.json();
    return data;
  } catch (error) {
    Logger.error(`Exception in getPowerBIEmbedResponse: ${error.message}`);
    throw error;
  }

Of course I send the reportID, datasetID and groupID of the report I want to obtain the embedToken. Why I still have the issue? I tried to get the Bearer token with both the url you can see in the code (one is commented), but still. I suppose there is another way to obtain the Bearer token used to retrieve the Embed Token

I already have found other similar issues on Stack Overflow, but still have issue to retrieving the embed token in Node.js, with the message:

2025-03-07T08:31:35.098660921Z Error: Failed to get embed token: 401 Unauthorized -
2025-03-07T08:31:35.098716024Z     at /app/src/services/PowerBIService.ts:135:13
2025-03-07T08:31:35.098722924Z     at Generator.next (<anonymous>)
2025-03-07T08:31:35.098728225Z     at fulfilled (/app/src/services/PowerBIService.ts:5:58)
2025-03-07T08:31:35.098733225Z     at processTicksAndRejections (node:internal/process/task_queues:95:5)

I already:

  • Created a Workspace in PowerBI
  • Assigned to the Workspace all the necessary API Authorizations
  • Created a new App in Azure
  • Given the PowerBI Authorization on the Azure App
  • Created a Security Group with the App (service principal)
  • Assigned as Admin role that Security Group to the PowerBI's Workspace
  • Enabled all the necessary stuffs on Admin Portal of PowerBI, Tenant Settings

The method I Created is this, I use ClientSecretCredentials with the Tenant ID, Client ID and Client Secret of the app:

async function getPowerBIEmbedResponse(
  reportId: string,
  datasetId: string,
  groupId: string
): Promise<any> {
  Logger.info("Inside getPowerBIEmbedResponse");

  try {
    const credential = new ClientSecretCredential(
      "bbbb", // Tenant ID
      "aaaa", // App Registration client ID
      "abcd" // Client secret
    );

    const tokenResponse = await credential.getToken(
      "https://analysis.windows/powerbi/api/.default"
    );

    // const tokenResponse = await credential.getToken(
    //   "https://graph.microsoft/.default"
    // );

    if (!tokenResponse || !tokenResponse.token) {
      throw new Error("Failed to retrieve Azure access token.");
    }

    Logger.info("Token obtained successfully");
    const accessToken = tokenResponse.token;

    const url = `https://api.powerbi/v1.0/my/groups/${groupId}/reports/${reportId}/GenerateToken`;
    // https://api.powerbi/v1.0/my/GenerateToken

    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify({
        accessLevel: "View",
        datasetId: datasetId,
      }),
    });

    if (!response.ok) {
      const errorText = await response.text();
      Logger.error(`Error response body: ${errorText}`);
      throw new Error(
        `Failed to get embed token: ${response.status} ${response.statusText} - ${errorText}`
      );
    }

    const data = await response.json();
    return data;
  } catch (error) {
    Logger.error(`Exception in getPowerBIEmbedResponse: ${error.message}`);
    throw error;
  }

Of course I send the reportID, datasetID and groupID of the report I want to obtain the embedToken. Why I still have the issue? I tried to get the Bearer token with both the url you can see in the code (one is commented), but still. I suppose there is another way to obtain the Bearer token used to retrieve the Embed Token

Share edited Mar 7 at 11:24 Giacomo Brunetta asked Mar 7 at 11:06 Giacomo BrunettaGiacomo Brunetta 1,5773 gold badges22 silver badges39 bronze badges 11
  • Check this stackoverflow/questions/79394771/… – Rukmini Commented Mar 7 at 11:20
  • As I said, I already checked other Stack Overflow's responses and I already did all of those steps, including enable the stuffs in Admin Portal. I think the issue is how to I retrieve Bearer token – Giacomo Brunetta Commented Mar 7 at 11:23
  • Did you add the service principal under Power BI workspace as Admin or Contributor? – Rukmini Commented Mar 7 at 13:58
  • Yes I did! Actually I can't add the service principal itself, but I added it in a securty group and I added it as admin. I was trying also to get this call on postman to retrieve the bearer token: login.microsoftonline/[tenant id]/oauth2/token and this that use the bearer token to get the embed token: api.powerbi/v1.0/my/groups/[group id]/reports/[report id]/GenerateToken But still the same issue. Now I noticed that I miss "Tenant" api permission, so I added, but the issue still – Giacomo Brunetta Commented Mar 7 at 15:04
  • Are you okay to generate token with use interactive flow? – Rukmini Commented Mar 7 at 15:28
 |  Show 6 more comments

2 Answers 2

Reset to default 1

I tried to call GenerateToken API for the existing/old workspace and got the same error:

POST https://api.powerbi/v1.0/my/groups/GroupID/reports/ReportID/GenerateToken

{
  "accessLevel": "View",
  "allowSaveAs": "true"
}

To resolve the error, you need to create a new workspace, as some APIs for service principal authentication only work with new Power BI workspaces.

Create a Microsoft Entra ID application and grant application type Tenant.ReadWrite.All type API permission:

Make sure to add the Service Principal as Admin to the newly created workspace:

Also make sure to enable the option Service principals can use Fabric APIs to the entire anization or specific security groups based on your requirement:

For sample, I generate access token by using below parameters:

https://login.microsoftonline/TenantID/oauth2/v2.0/token

client_id: ClientID
client_secret: Secret
scope: https://analysis.windows/powerbi/api/.default
grant_type: client_credentials

I am able to call the API successfully for the new created workspace:

POST https://api.powerbi/v1.0/my/groups/GroupID/reports/ReportID/GenerateToken

{
  "accessLevel": "View",
  "allowSaveAs": "true"
}

Hence alternatively create new workspace and check.

Fixed and tested using Postman. Executing this POST API:

https://api.powerbi/v1.0/my/groups/[groupID]/reports/[reportID]/GenerateToken

with body:

{
  "accessLevel": "View",
  "identities": [
    {
      "username": "username",
      "roles": []
    }
  ],
  "datasets": [
    {
      "id": "[datasetID]"
    }
  ]
}

I had 2 issues:

  • The first issue was related to the client_id and secret I was using to create the Bearer token needed for it, I used the one of the wrong Service Principal

  • Then, I had this issue:

{
    "error": {
        "code": "InvalidRequest",
        "message": "Creating embed token with effective identity requires dataset to be provided"
    }
}

and this was related to the body I sent. Effective Identity was not supported for the dataset chosen, it is used only for Row Level Security (RLS), meaning that I had to remove it and keep this body:

{
  "accessLevel": "View",
  "datasets": [
    {
      "id": "[datasetID]"
    }
  ]
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744934450a4601932.html

相关推荐

  • node.js - Unauthorized to retrieve PowerBI embed token - Stack Overflow

    I already have found other similar issues on Stack Overflow, but still have issue to retrieving the emb

    1天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信