March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early bird discount ends December 31.
Register NowBe one of the first to start using Fabric Databases. View on-demand sessions with database experts and the Microsoft product team to learn just how easy it is to get started. Watch now
Hi,
Following this tutorial and Embedding with non-Power BI users, I already successfully embeded dashboard for non-Power BI users.
I've used the approach of retrieving access token for master account (pro) with username and password.
Then generating embed token with access token.
I have to say that there is lack of API documentation for non C# developers.
Also when there is error - no error code given or explanation. Not developer friendly at all.
Below is simple examle of embeding Dashboard with PHP:
<?php $ch_access_token = curl_init(); $oauth_data = [ 'grant_type' => 'password', 'username' => 'master-usern@domain.onmicrosoft.com', 'password' => '123456', 'client_id' => 'x7957710-04xc-1a345-1234-097d273f4az2', 'resource' => 'https://analysis.windows.net/powerbi/api', ]; curl_setopt($ch_access_token, CURLOPT_URL, 'https://login.microsoftonline.com/common/oauth2/token'); curl_setopt($ch_access_token, CURLOPT_POST, 1); curl_setopt($ch_access_token, CURLOPT_POSTFIELDS, http_build_query($oauth_data)); // receive server response ... curl_setopt($ch_access_token, CURLOPT_RETURNTRANSFER, true); $server_output_access_token = curl_exec($ch_access_token); curl_close($ch_access_token); $token_data = json_decode($server_output_access_token, true); $access_token = $token_data['access_token'] ?? ''; if (!$access_token) { die('NA'); } $ch_entity_token = curl_init(); $json_body = [ 'accessLevel' => 'View' ]; $group_id = 'ad567a8z-088x-1234-3456-112255a2a5a2'; $entity_id = 'zb567a8z-088x-1234-448-33775a2a5a2b'; curl_setopt($ch_entity_token, CURLOPT_URL, "https://api.powerbi.com/v1.0/myorg/groups/{$group_id}/dashboards/{$entity_id}/GenerateToken" ); curl_setopt($ch_entity_token, CURLOPT_POST, 1); curl_setopt($ch_entity_token, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json; charset=utf-8', "Authorization: Bearer {$access_token}" ]); curl_setopt($ch_entity_token, CURLOPT_POSTFIELDS, json_encode($json_body)); // receive server response ... curl_setopt($ch_entity_token, CURLOPT_RETURNTRANSFER, true); $server_output_dashboard_token = curl_exec($ch_entity_token); curl_close($ch_entity_token); $entity_token_data = json_decode($server_output_dashboard_token, true); if (!isset($entity_token_data['token'])) { die('NA'); } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Test page</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <script src="js/powerbi.js"></script> <style> html { height: 100%; } </style> </head> <body style="height: 100%"> <div id="dashboardContainer" style="height: 100%"> </div> <script> // Read embed application token from Model var accessToken = "<?=$entity_token_data['token']?>"; // Read dashboard Id from Model var embedEntityId = "<?=$entity_id?>"; // Read embed URL from Model var embedUrl = 'https://app.powerbi.com/dashboardEmbed'; // Get models. models contains enums that can be used. var models = window['powerbi-client'].models; // Embed configuration used to describe the what and how to embed. // This object is used when calling powerbi.embed. // This also includes settings and options such as filters. // You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details. var config = { type: 'dashboard', tokenType: models.TokenType.Embed, accessToken: accessToken, embedUrl: embedUrl, id: embedEntityId }; // Get a reference to the embedded dashboard HTML element var dashboardContainer = $('#dashboardContainer')[0]; // Embed the dashboard and display it within the div container. var dashboard = powerbi.embed(dashboardContainer, config); </script>
So far so good. Dashboard embeded. True fullstack I am.
Lets copy-paste above code, replace dashboard with report and we will have report embeded you would say.
Well, maybe with another API's but not with microsoft lol.
Below is implementation of report embed:
<?php $ch_access_token = curl_init(); $oauth_data = [ 'grant_type' => 'password', 'username' => 'master-usern@domain.onmicrosoft.com', 'password' => '123456', 'client_id' => 'x7957710-04xc-1a345-1234-097d273f4az2', 'resource' => 'https://analysis.windows.net/powerbi/api', ]; curl_setopt($ch_access_token, CURLOPT_URL, 'https://login.microsoftonline.com/common/oauth2/token'); curl_setopt($ch_access_token, CURLOPT_POST, 1); curl_setopt($ch_access_token, CURLOPT_POSTFIELDS, http_build_query($oauth_data)); // receive server response ... curl_setopt($ch_access_token, CURLOPT_RETURNTRANSFER, true); $server_output_access_token = curl_exec($ch_access_token); curl_close($ch_access_token); $token_data = json_decode($server_output_access_token, true); $access_token = $token_data['access_token'] ?? ''; if (!$access_token) { die('NA'); } $ch_entity_token = curl_init(); $json_body = [ 'accessLevel' => 'View' ]; $group_id = 'ad567a8z-088x-1234-3456-112255a2a5a2'; $entity_id = 'zb567a8z-088x-1234-448-33775a2a5a2b'; curl_setopt($ch_entity_token, CURLOPT_URL, "https://api.powerbi.com/v1.0/myorg/groups/{$group_id}/reports/{$entity_id}/GenerateToken" ); curl_setopt($ch_entity_token, CURLOPT_POST, 1); curl_setopt($ch_entity_token, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json; charset=utf-8', "Authorization: Bearer {$access_token}" ]); curl_setopt($ch_entity_token, CURLOPT_POSTFIELDS, json_encode($json_body)); // receive server response ... curl_setopt($ch_entity_token, CURLOPT_RETURNTRANSFER, true); $server_output_report_token = curl_exec($ch_entity_token); curl_close($ch_entity_token); $entity_token_data = json_decode($server_output_report_token, true); if (!isset($entity_token_data['token'])) { die('NA'); } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Test page</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <script src="js/powerbi.js"></script> <style> html { height: 100%; } </style> </head> <body style="height: 100%"> <div id="reportContainer" style="height: 100%"> </div> <script> // Read embed application token from Model var accessToken = "<?=$entity_token_data['token']?>"; // Read report Id from Model var embedEntityId = "<?=$entity_id?>"; // Read embed URL from Model var embedUrl = 'https://app.powerbi.com/reportEmbed'; // Get models. models contains enums that can be used. var models = window['powerbi-client'].models; // Embed configuration used to describe the what and how to embed. // This object is used when calling powerbi.embed. // This also includes settings and options such as filters. // You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details. var config = { type: 'report', tokenType: models.TokenType.Embed, accessToken: accessToken, embedUrl: embedUrl, id: embedEntityId }; // Get a reference to the embedded report HTML element var reportContainer = $('#reportContainer')[0]; // Embed the report and display it within the div container. var report = powerbi.embed(reportContainer, config); </script>
Generate embed token for report return 401 Unauthorized
Howewer the response from access token has all necessary scopes:
Access token request's response:
{ "token_type": "Bearer", "scope": "Dashboard.Read.All Dataset.Read.All Group.Read Report.ReadWrite.All", "expires_in": "3600", "ext_expires_in": "0", "expires_on": "1498449876", "not_before": "1498445976", "resource": "https://analysis.windows.net/powerbi/api", "access_token": "eyJ0eXAiO...T3DwV2XQ", "refresh_token": "AQABAAAAAABnfiG-...-Wzb-zqO1ExGK31EUyy8gAA" }
Embed token request (return 401):
POST /v1.0/myorg/groups/ad567a8z-088x-1234-3456-112255a2a5a2/reports/zb567a8z-088x-1234-448-33775a2a5a2b/GenerateToken HTTP/1.1 Host: api.powerbi.com Content-Type: application/json; charset=utf-8 Authorization: Bearer eyJ0eXAiO...T3DwV2XQ {"accessLevel": "View", "allowSaveAs": false}
Few more details:
- I have pro license (trial)
- Report is part of group(workspace)
- Application was created through https://dev.powerbi.com/apps
- All permissions was set in AD
Any 5 cents appresiated.
Regards.
Hello
I want to reproduce this part on C# to manage row level security with php code.
Any help ?
GenerateTokenRequest generateTokenRequestParameters; // This is how you create embed token with effective identities if (!string.IsNullOrEmpty(username)) { var rls = new EffectiveIdentity(username, new List<string> { report.DatasetId }); if (!string.IsNullOrWhiteSpace(roles)) { var rolesList = new List<string>(); rolesList.AddRange(roles.Split(',')); rls.Roles = rolesList; } // Generate Embed Token with effective identities. generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view", identities: new List<EffectiveIdentity> { rls }); } else { // Generate Embed Token for reports without effective identities. generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view"); }
@calm1kov wrote:
Howewer the response from access token has all necessary scopes:
Access token request's response:
{ "token_type": "Bearer", "scope": "Dashboard.Read.All Dataset.Read.All Group.Read Report.ReadWrite.All", "expires_in": "3600", "ext_expires_in": "0", "expires_on": "1498449876", "not_before": "1498445976", "resource": "https://analysis.windows.net/powerbi/api", "access_token": "eyJ0eXAiO...T3DwV2XQ", "refresh_token": "AQABAAAAAABnfiG-...-Wzb-zqO1ExGK31EUyy8gAA" }
- Application was created through https://dev.powerbi.com/apps
- All permissions was set in AD
Based on my test, that scope is sufficient to request a dashboard embedtoken however not for a report embedtoken.
When all permissions are checked, I get the accesstoken with scope like
"token_type": "Bearer", "scope": "Content.Create Dashboard.Read.All Data.Alter_Any Dataset.Read.All Dataset.ReadWrite.All Group.Read Group.Read.All Metadata.View_Any Report.Read.All Report.ReadWrite.All",
When did you check all permissions in AD? Even though I'm not an expert on AAD, I think you have the same "re-prompt the user with the consent page" in this thread. The the permission doesn't change at all even though you already set all permission before re-consent. I'm not aware of how to re-consent, however you could follow below steps to grant all permission initially and it indeed works to request a report embedtoken base on my test.
1.Register a app through https://dev.powerbi.com/apps.
2.Check all permissions and save.
3.Grant permission.
4. Request accesstoken with this client_id.
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!
Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.
User | Count |
---|---|
8 | |
1 | |
1 | |
1 | |
1 |
User | Count |
---|---|
9 | |
3 | |
2 | |
2 | |
2 |