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

Calling all Data Engineers! Fabric Data Engineer (Exam DP-700) live sessions are back! Starting October 16th. Sign up.

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
FabCon Global Hackathon Carousel

FabCon Global Hackathon

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes!

September Power BI Update Carousel

Power BI Monthly Update - September 2025

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

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.