Forum Discussion
400 Bad Request Error when embedding report
- Anonymous6 years ago
Hi shaw
If you are using the 'App owns data' type of embedding + using the Service Principal to generate embedding tokens, then this Identity section of the token request should contain details of the 'user' used for Row Level Security purposes.
Are you reports/dashboards using Row Level Security?
If so... your identity section should look like this..."identities": [ { "username": "[email protected]", "roles": [ "My PBI Role Name" ], "datasets": [ "cfafbeb1-8037-4d0c-896e-a46fb27ff229" ] } ]Username can be any value - you are effectively impersonating this person - and this has no link to any account in your Azure tenant or Power BI access list.
Roles should contain any Power BI (RLS) roles that you have defined inside your data model. Note that you should not supply roles here if you are not using RLS - and dont supply roles that dont exist in your model. Again, this is not a role that belongs to your Service Principal account or any other Power BI account type (admin/member/viewer) etc..Hope this helps,
Cheers - Matt
Hi Anonymous
Appreciate your help here.
I tried to pass on the JSON to the request header as you suggested with the role I am using. My scenario is that the user from a school would login, based on their schoolid I am performing RLS. Role I have set is 'school' which I have mentioned correctly. I am not sure how to pass on the rule. I couldn't find any help on the community or through the official reference.
From the UI, once the user authenticates in our web app, we will pass on the schoolid to the ajax call.
{
"datasets": [
{
"id": "18727ad-680b-4248-b571-xxxxxxxxxxxx"
}
],
"reports": [
{
"id": "xxxxxx7-31e9-4a28-8317-047df26b908c"
}
],
"identities": [
{
"username": "[email protected]",
"roles": [
"school"
],
"datasets": [
"18727ad-680b-4248-b571-xxxxxxxxxxxx"
]
}
]
} My assumption is that I will be passing the rule through the report.setFilter() from the AJAX call through the javascript.
However, on both the Java & Javascript end, what would go in the perfect scenario?
Hi shaw
It is worth considering the differences in behaviours between roles in Row Level Security - and report level filters.
It sounds as though something like 'School ID' would ensure that a user can only see data belonging to that particular school?
If that is the case... then Row Level Security is probably the thing to use!
The username field in the identities object in the token generation request - could be the users School ID (if you don't need to reference the email address or other identifier in your RLS roles).
Generating this token should then be done server side where the details cannot be tampered with.
The downside of simply passing through something like 'School ID' into a report level filter, is that this is done in JavaScript and can be easily manipulated.
Another aspect of report level filters is that it is possible to write Power BI measures in your data model that escape/break-out of this filter context. This can result in measures (say a count of students) being performed across ALL schools - when you were perhaps intending on limiting it to ONLY the school ID that the user has access to.
Row Level Security roles work differently to this... so once set, measures cannot retrieve data outside of the scope of that security rule.
It is tricky to build up a picture of your requirements without seeing a full data model... but I hope some of this makes sense / is useful.
- shaw6 years agoFrequent Visitor
Hi Anonymous
Imagine, I have a 'School ID' set as a role (Power BI role) as an RLS field. How do I pass on the 'School ID' to the Ajax call from the alien application?
Javascript (Ajax Call with School ID) > Alien application's Java code in order to embed the Power BI report?
Technically saying:
I would like to pass on the "school ID" that I got as a global variable in the alien application readily available to pass on. I couldn't figure out how it is done on the https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html# .
my School ID is a column from the table called "SchooldDetails"
report. <I pass on the constructed table and column info to this object? >$.ajax({ type: "GET", url: "/appownsdatasample/getembedinfo", dataType: "json", success: function (embedData) { reportLoadConfig["accessToken"] = embedData["embedToken"]; reportLoadConfig["embedUrl"] = embedData["embedUrl"]; // Use the token expiry to regenerate Embed token for seamless end user experience // Refer https://aka.ms/RefreshEmbedToken tokenExpiry = embedData["tokenExpiry"] // Embed Power BI report when Access token and Embed URL are available report = powerbi.embed(reportContainer, reportLoadConfig); // Triggers when a report schema is successfully loaded report.on("loaded", function () { console.log("Report load successful"); }); // Triggers when a report is successfully embedded in UI report.on("rendered", function () { console.log("Report render successful"); });- Anonymous6 years agoNot applicable
Hi shaw
Apologies for the lack of response, the last few weeks have been difficult to say the least.
Are you still having issues with RLS and getting your ID's to the right place?
Happy to continue the discussion if you are stuck.