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

Find everything you need to get certified on Fabric—skills challenges, live sessions, exam prep, role guidance, and more. Get started

Reply
francescod9
New Member

Embedded Report render failed on API request

I have an app registration that I'm using in my application to access the Microsoft Calendar.
I want to embed a report into my app but I want to avoid the user to login everytime to view the redered report. I added the required permissions (Report.Read.All, Workspace.Read.All, Dashboard.Read.All) to my app registration on the Azure Portal.
To test the permission I tried to render the embedded iframe with the src param compiled and it worked correctly but I had to login every time I opened the html file, so I tried to retrieve the access token from the Microsoft login API (https://login.microsoftonline.com/common/oauth2/v2.0/token) but I had that the origin is not correct and should must be a Single Page Application. Despite I added the http://localhost URI on the Azure Application SPA panel, this error came anyway.

I hard coded the access token statically and I tried to retrieve the report from the Reports API (https://api.powerbi.com/v1.0/myorg/reports/{reportId}) but this time I got a 403 reponse with no body, both on the fetch call on the html and on postman.
Is there anything I'm missing or is there a better way to do this? Thanks.

 

 

 

<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.23.1/powerbi.min.js"></script>

 

 

 

 

 

 

 

        // Login data.
        const refreshToken = "REFRESH_TOKEN";
        const clientId = "CLIENT_ID";
        const tenantId = "TENANT_ID";
        const scope = ".default";
        const grantType = "refresh_token";
        const clientSecret = "CLIENT_SECRET";
       
        // Report data.
        const reportId = "REPORT_ID";
 
        const accessToken = "ACCESS_TOKEN"
 
        async function getAccessToken() {
            // const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
            // const response = await fetch(url, {
            //     method: 'POST',
            //     headers: {
            //         'Content-Type': 'application/x-www-form-urlencoded'
            //     },
            //     body: new URLSearchParams({
            //         'grant_type': 'client_credentials',
            //         'client_id': clientId,
            //         'client_secret': clientSecret,
            //         'scope': 'https://graph.microsoft.com/.default'
            //     })
            // });
            // const data = await response.json();
            // console.log(data);
            // return data.access_token;
            return accessToken;
        }
 
        async function getEmbedDetails() {
            const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
            const response = await fetch(url, {
                headers: {
                    'Authorization': `Bearer ${accessToken}`
                }
            });
            const data = await response.json();
            return data;
        }
 
        (async () => {
            try {
                const accessToken = await getAccessToken();
                const embedDetails = await getEmbedDetails();
                const embedUrl = embedDetails.embedUrl;
 
                const models = window['powerbi-client'].models;
                const embedConfig = {
                    type: 'report',
                    tokenType: models.TokenType.Embed,
                    accessToken: accessToken,
                    embedUrl: embedUrl,
                    id: reportId,
                    permissions: models.Permissions.All,
                    settings: {
                        filterPaneEnabled: false,
                        navContentPaneEnabled: true
                    }
                };
 
                const reportContainer = document.getElementById('reportContainer');
                powerbi.embed(reportContainer, embedConfig);
            } catch (error) {
                console.error('Error embedding Power BI report:', error);
            }
        })();

 

 

 

 

 

1 ACCEPTED SOLUTION
hackcrr
Super User
Super User

Hi, @francescod9 

403 Forbidden error:
You should ensure that your application is registered with the correct API permissions and has administrator consent. Double-check the Client ID, Client Secret, and Tenant ID. access tokens have a limited validity period. If a session lasts longer than the token's expiration date, ensure that the token is refreshed periodically.
Ensure that your application registration is properly configured to allow CORS from the application domain.

In Application Registration, go to API Permissions and add the permissions required by Power BI (e.g., , , Report.Read.All).Workspace.Read.AllDashboard.Read.All grants the administrator consent for these permissions.

To obtain an access token using the client credential stream, you can use the following code:

async function getAccessToken() {
    const tenantId = "YOUR_TENANT_ID";
    const clientId = "YOUR_CLIENT_ID";
    const clientSecret = "YOUR_CLIENT_SECRET";
    const scope = "https://analysis.windows.net/powerbi/api/.default";
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;

    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams({
            'grant_type': 'client_credentials',
            'client_id': clientId,
            'client_secret': clientSecret,
            'scope': scope
        })
    });

    const data = await response.json();
    if (response.ok) {
        return data.access_token;
    } else {
        throw new Error(data.error_description);
    }
}

Using the acquired access token, you can embed the report into your application:

<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.23.1/powerbi.min.js"></script>

<div id="reportContainer" style="height: 600px;"></div>

<script>
    const reportId = "YOUR_REPORT_ID";
    const accessToken = await getAccessToken(); // Call the function to get the access token

    async function getEmbedDetails() {
        const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
        const response = await fetch(url, {
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        });
        const data = await response.json();
        return data;
    }

    (async () => {
        try {
            const embedDetails = await getEmbedDetails();
            const embedUrl = embedDetails.embedUrl;

            const models = window['powerbi-client'].models;
            const embedConfig = {
                type: 'report',
                tokenType: models.TokenType.Embed,
                accessToken: accessToken,
                embedUrl: embedUrl,
                id: reportId,
                permissions: models.Permissions.All,
                settings: {
                    filterPaneEnabled: false,
                    navContentPaneEnabled: true
                }
            };

            const reportContainer = document.getElementById('reportContainer');
            powerbi.embed(reportContainer, embedConfig);
        } catch (error) {
            console.error('Error embedding Power BI report:', error);
        }
    })();
</script>

 

hackcrr

If this post helps, then please consider Accept it as the solution and kudos to this post to help the other members find it more quickly

View solution in original post

2 REPLIES 2
francescod9
New Member

We tried. 
CORS error was thrown by the Live Server. We tried to do the same calls from a NodeJS Server and we got the access token.
The problem now is that the getEmbedDetails call returns a 401 Status respost both from NodeJS and postman.
THe following code is the actual NodeJS code that we are using:

async function getAccessToken() {
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
 
    const response = await axios.post(url, {
        'grant_type': 'client_credentials',
        'client_id': clientId,
        'client_secret': clientSecret,
        'scope': "https://analysis.windows.net/powerbi/api/.default"
    },
    {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    });
 
    return response.data.access_token;
}
 
async function getEmbedDetails() {
    let accessToken = await getAccessToken();
 
    const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
    const response = await axios.get(url, {
        headers: {
            'Authorization': `Bearer ${accessToken}`
        }
    }).catch((error) => {
        console.log(error)});
    return response.data;
}
 
getEmbedDetails().then((data) => {
    console.log(data);
});

Are we missing any step?
 

hackcrr
Super User
Super User

Hi, @francescod9 

403 Forbidden error:
You should ensure that your application is registered with the correct API permissions and has administrator consent. Double-check the Client ID, Client Secret, and Tenant ID. access tokens have a limited validity period. If a session lasts longer than the token's expiration date, ensure that the token is refreshed periodically.
Ensure that your application registration is properly configured to allow CORS from the application domain.

In Application Registration, go to API Permissions and add the permissions required by Power BI (e.g., , , Report.Read.All).Workspace.Read.AllDashboard.Read.All grants the administrator consent for these permissions.

To obtain an access token using the client credential stream, you can use the following code:

async function getAccessToken() {
    const tenantId = "YOUR_TENANT_ID";
    const clientId = "YOUR_CLIENT_ID";
    const clientSecret = "YOUR_CLIENT_SECRET";
    const scope = "https://analysis.windows.net/powerbi/api/.default";
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;

    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams({
            'grant_type': 'client_credentials',
            'client_id': clientId,
            'client_secret': clientSecret,
            'scope': scope
        })
    });

    const data = await response.json();
    if (response.ok) {
        return data.access_token;
    } else {
        throw new Error(data.error_description);
    }
}

Using the acquired access token, you can embed the report into your application:

<script src="https://cdnjs.cloudflare.com/ajax/libs/powerbi-client/2.23.1/powerbi.min.js"></script>

<div id="reportContainer" style="height: 600px;"></div>

<script>
    const reportId = "YOUR_REPORT_ID";
    const accessToken = await getAccessToken(); // Call the function to get the access token

    async function getEmbedDetails() {
        const url = `https://api.powerbi.com/v1.0/myorg/reports/${reportId}`;
        const response = await fetch(url, {
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        });
        const data = await response.json();
        return data;
    }

    (async () => {
        try {
            const embedDetails = await getEmbedDetails();
            const embedUrl = embedDetails.embedUrl;

            const models = window['powerbi-client'].models;
            const embedConfig = {
                type: 'report',
                tokenType: models.TokenType.Embed,
                accessToken: accessToken,
                embedUrl: embedUrl,
                id: reportId,
                permissions: models.Permissions.All,
                settings: {
                    filterPaneEnabled: false,
                    navContentPaneEnabled: true
                }
            };

            const reportContainer = document.getElementById('reportContainer');
            powerbi.embed(reportContainer, embedConfig);
        } catch (error) {
            console.error('Error embedding Power BI report:', error);
        }
    })();
</script>

 

hackcrr

If this post helps, then please consider Accept it as the solution and kudos to this post to help the other members find it more quickly

Helpful resources

Announcements
Sept PBI Carousel

Power BI Monthly Update - September 2024

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

September Hackathon Carousel

Microsoft Fabric & AI Learning Hackathon

Learn from experts, get hands-on experience, and win awesome prizes.

Sept NL Carousel

Fabric Community Update - September 2024

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

Top Solution Authors