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

Compete to become Power BI Data Viz World Champion! First round ends August 18th. Get started.

Reply
muzammilinamdar
Regular Visitor

Embedding Dashboard with Service Principal getting 403 Error

Hi Team, We have a Dashboard that reads from multiple semantic models and data sources, some of these data sources have Effective Identity enabled, we have created out Request Body to generate the dashboard token via `https://api.powerbi.com/v1.0/myorg/GenerateToken` URL the token is generating without any issues, but when we use the token in the frontend to embedd the iframe it doesn't work. 

This is the request body shape to the URL.

 

    request_body = {
    "dashboards": [
        {
            "id": ""
        }
    ],
    "datasets": [
        {
            "xmlaPermissions": "ReadOnly",
            "id": ""
        }
    ],
    "accessLevel": "View",
    "identities": [
        {
            "username": user,
            "roles": [
                ""
            ],
            "datasets": [
                ""
            ]
        },
    ]
}
 

 


This is how i am using the embed token in the frontend

 

'use client';

import { ErrorAlert } from '@/app/components/lib/ErrorAlert';
import { WbSpinner, WbSelect } from '@workbench/react';
import { PowerBIEmbed } from 'powerbi-client-react';
import { models } from 'powerbi-client';
import { useEffect, useState } from 'react';
import { useApps } from '../../context/AppsContext';
import styles from './layout.module.scss';
import { Embed, Report, Dashboard, Page } from 'powerbi-client';
import { PbiApps } from '@/app/types/PbiApps';

// TODO Add Error Fallback
export default function Layout({ params }: { params: { app_id: string } }) {
  const [showReport, setShowReport] = useState(false);
  const [embedToken, setEmbedToken] = useState('');
  const [reportId, setReportId] = useState('');
  const [app_type, setApp_type] = useState('');
  const [showErrorDefault, setShowErrorDefault] = useState(false);
  const [showErrorUnauthorized, setShowErrorUnauthorized] = useState(false);
  const { appsData } = useApps();
  const [preport, setPreport] = useState<Dashboard>();
  const [pages, setPages] = useState<Page[]>([]);
  const [currentPageName, setCurrentPageName] = useState('');
  const [pageList, setPageList] = useState<string[]>([]);

  // TODO look into request error in first render (not causing any issues)
  useEffect(() => {
    const report = appsData?.find((app) => app.app_id === params.app_id);
    const isRls = report?.rls ? true : false;
    report &&
      fetch(`/api/pbiEmbedToken/${params.app_id}?rls=${isRls}`)
        .then((res) => res.json())
        .then((data) => {
          if (data.status === 401) {
            setShowErrorUnauthorized(true);
          }
          const token = data;
          const reportId = report?.report_id;
          setReportId(reportId ?? '');
          setEmbedToken(token);
          setShowReport(true);
          setApp_type(report?.is_dashboard ? 'dashboard' : 'report');
        })
        .catch((error) => {
          setShowErrorDefault(true);
        });
      fetch(`/api/app/${params.app_id}`)
        .then((res) => res.json())
        .then((data) => {
          const app = Object.values(data[0])[0] as PbiApps;
          setPageList(app?.pages || [])    
      })
      .catch((error) => {
        setShowErrorDefault(true);
      });
  }, [appsData, params.app_id]);

  // useEffect(() => {
  //   if (preport) {
  //     preport.on('loaded', () => {
  //       preport.getPages().then((pages) => {
  //         setPages(pages);
  //       });
  //     });
  //   }
  // }, [preport]);

  if (showErrorUnauthorized) {
    return (
      <ErrorAlert
        message={
          "No matching entitlements. Please reach out to the report's responsible person."
        }
      />
    );
  }

  if (showErrorDefault) {
    return (
      <ErrorAlert
        message={
          "App could not be loaded. Please reach out to the report's responsible person."
        }
      />
    );
  }

  if (reportId === '') {
    return (
      <div className={styles.loadingSpinnerContainer}>
        <WbSpinner className={styles.loadingSpinner}></WbSpinner>
      </div>
    );
  }

  const embedConfig =  {
    type: "dashboard",
    id: "",
    accessToken: "",
    tokenType: models.TokenType.Embed,
    embedUrl: "https://app.powerbi.com/dashboardEmbed",
    settings: {
      filterPaneEnabled: false,
      navContentPaneEnabled: false,
    },
  };

  return (
    <div>
      <div className={styles.reportContainer}>
        {showReport && embedToken && (
          <PowerBIEmbed
            cssClassName={pageList.length === 0 ? styles.iframeContainer : styles.iframeContainerMain}
            embedConfig={embedConfig}
            getEmbeddedComponent={(embedObject: Embed) => {
              if (embedObject instanceof Dashboard) {
                setPreport(embedObject);
              }
            }}
          />
        )}
      </div>
    </div>
  );
}

 

 

7 REPLIES 7
lbendlin
Super User
Super User

ome of these data sources have Effective Identity enabled,

How are you presenting yourself to these data sources? Can't use the service principal for that, so you would need to have  a user mapping table for each?

@lbendlin 

 

We are encountering an access issue while trying to embed a Power BI dashboard using a service principal. We are making a request to the following API endpoint:

This API successfully returns the embedUrl. However, when attempting to access the embedUrl, we receive a 403 Forbidden error.

Steps Taken:

  1. Service Principal Configuration:

    • The service principal has been added as a member to the workspace.
    • The necessary API permissions have been granted in Azure AD:
      • Dashboard.ReadWrite.All
      • Dashboard.Read.All
    • Admin consent has been provided for these permissions.
  2. Troubleshooting Attempts:

    • Verified that the service principal is correctly assigned to the workspace.
    • Confirmed that the Power BI tenant settings allow service principals to use Power BI APIs.
    • Regenerated the authentication token and verified that the required scopes are included.
    • Ensured that the request is using a valid access token with the correct authorization headers.

Request for Assistance:

Could you please confirm if additional permissions or configurations are required to access the embedUrl successfully? Additionally, are there any specific Power BI security policies that could be blocking access?

Your guidance on resolving this issue would be highly appreciated.

 

Thanks

Ashwini

Please confirm that you really want to embed a Dashboard.  What is the expected user experience?

 

Embedding is usually done with reports.

Hi @lbendlin  ,

 

Thanks for your reply.

Yes, we are working on embedding the Power BI dashboard to display it in the frontend UI of our React application for an improved user experience.

 

Thanks,

Ashwini

If you have a Pro license you can open a Pro ticket at https://admin.powerplatform.microsoft.com/newsupportticket/powerbi
Otherwise you can raise an issue at https://community.fabric.microsoft.com/t5/Issues/idb-p/Issues .

@lbendlin Can you please elaborate or point me to a resource which mentions that data sources with EI enabled cannot be used with Service Principal. 

Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

Check out the August 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

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