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
2 Answers
Reset to default 1I 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
评论列表(0条)