Adamwallace3
Paso 1: autorizar la aplicación
Registrar aplicación
Usé una aplicación nativa, fue la solución más simple. Puede usar una aplicación web de servidor, pero deberá agregar client_secret en cualquier lugar que vea client_id en este tutorial. Necesitará al menos tener habilitados los permisos de lectura.
Paso 2: Obtén el token de acceso (publicación)
POST: https://login.microsoftonline.com/common/oauth2/token data: { grant_type: password scope: openid resource: https://analysis.windows.net/powerbi/api client_id: {Client ID} username: {PBI Account Username} password: {PBI Account Username} } --Returns Json: { "token_type": "Bearer", "scope": "Report.Read.All ...", "expires_in": "xxxx", "ext_expires_in": "0", "expires_on": "xxxxxxxxxx", "not_before": "xxxxxxxxxxx", "resource": "https://analysis.windows.net/powerbi/api", "access_token": "eyJ0eXAi...", "refresh_token": "AQABA...", "id_token": "eyJ...." }
Paso 3: Obtenga los detalles del informe:
Esto se puede hacer de dos formas diferentes. La forma más sencilla es navegar a su informe en el sitio web de Power Bi y extraer la identificación del informe y la identificación del grupo de la URL.
https://app.powerbi.com/groups/{GROUP ID}/reports/{REPORT ID}/ReportSection
Necesitaba extraer diferentes informes de un grupo determinado, así que aquí está la solicitud de obtención para hacerlo.
OBTENGA https://api.powerbi.com/v1.0/myorg/groups/{GROUP ID} / reports headers = {Authorization: Bearer + {access_token from first post}} Devuelve Json: {"@ odata.context": "http://wabi-west-us-redirect.analysis.windows.net/v1.0/myorg/groups/.../$metadata#reports", "valor": [ { "id": "...", "modelId": 0, "name": "...", "webUrl": "...", "embedUrl": "https://app.powerbi.com/reportEmbed?reportId={REPORT ID}&groupId={GROUP ID}", "isOwnedByMe": true, "isOriginalPbixReport": false, "datasetId": "..." }, ... Repeated for other Reports in Group }
Step 4: Get Embed token
In the old Power Bi server (through Azure) you could encode your own embed token, in the September 2017 update Microsoft started to require that you use the rest api or one of the available SDKs. In the «data» section you can pass arguments to implement row level security (link).
POST https://api.powerbi.com/v1.0/myorg/groups/{GROUP ID}/reports/{REPORT ID}/GenerateToken headers = { Authorization: Bearer + {access_token from first post} Content-Type:application/json; charset=utf-8 Accept:application/json } data= { "accessLevel": "View", "allowSaveAs": "false" } Returns Json: { "@odata.context": "http://wabi-west-us-redirect.analysis.windows.net/v1.0/myorg/groups/{GROUP_ID}/$metadata#Microsoft.PowerBI.ServiceContracts.Api.V1.GenerateTokenResponse", "token": "H4sIAAAAAAA...", "tokenId": "...", "expiration": "yyyy-mm-ddTxx:xxxxx" }
Step 5: Test
Go to the Microsoft Power BI Embedded Sample site (link) and test your report.
The input fields are as follows:
- Embed Token: {token from final post}
- Embed URL: https://app.powerbi.com/reportEmbed?reportId={REPORT ID}&groupId={GROUP ID}
- Report Id: {REPORT ID}
You can also test the embedded report using the following :
<html> <script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/jquery/dist/jquery.js"></script> <script src="https://microsoft.github.io/PowerBI-JavaScript/demo/node_modules/powerbi-client/dist/powerbi.js"></script> <script type="text/javascript"> window.onload = function () { var embedConfiguration = { type: 'report', accessToken: '{access_token}', embedUrl: 'https://app.powerbi.com/reportEmbed?reportId={REPORT ID}&groupId={GROUP ID}', id:'{REPORT ID}', settings: { {settings_ from link} } }; var $reportContainer = $('#dashboardContainer'); var report = powerbi.embed($reportContainer.get(0), embedConfiguration); } function reloadreport(){ var element = $('#dashboardContainer'); alert(element); var report = powerbi.get(element); report.reload().catch(error => {console.log(error) }); }; </script> <div id="dashboardContainer"></div> </html>
Notes:
Available settings can be found here.
Disclaimer:
This code comes with no warranty and no guarantees. It is HIGHLY likely that Microsoft will change something and this walkthrough will become depreciated. Please check your PowerBi agreement to make sure that the steps listed in this walkthrough adhere to the agreed upon terms.
Tags:
Python, embedded, token, access token, get, post, REST API, ruby, PHP
EDIT 1:
Added space to prevent 😮 and 😛 in code.
Edit 2:
Turned down sarcasm and added links.
alexbjorlig
Regarding the «Step 2: Get Access Token», how would you do this as a service principal?
andyparkerson
In response to alexbjorlig
To use service principal, use a grant type of `client_credentials` and replace the username and password with a client secret.
POST: https://login.microsoftonline.com/common/oauth2/token data: { grant_type: client_credentials scope: openid resource: https://analysis.windows.net/powerbi/api client_id: {Client ID}
client_secret: {Client Secret} }
Homeslyce
In response to alexbjorlig
I am not sure about your «service principal» thing, But if you asked «How to do get the access token with code and not Postman to use it in an application in production?» here is my function in .NET Core 3.1 that calls my powerBI app registered in Azure in the 1st step:
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
public async Task<AccessTokenResponse> GetAccessTokenAsync(string clientId)
{
HttpClient client = new HttpClient();
//Build request body
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("grant_type", "password");
data.Add("scope", "openid");
data.Add("resource", "https://analysis.windows.net/powerbi/api");
data.Add("client_id", clientId);
data.Add("username", "{your powerBI username}");
data.Add("password", "{your powerBI password}");
//The .ToKeyValue() function is taken from https://blog.bitscry.com/2018/12/14/creating-formurlencodedcontent-variables-from-objects/
FormUrlEncodedContent content = new FormUrlEncodedContent(data.ToKeyValue());
//Call request
HttpResponseMessage response = await client.PostAsync("https://login.microsoftonline.com/common/oauth2/token", content);
//request validation
response.EnsureSuccessStatusCode();
//Convert response into my custom class AccessTokenResponse that represents the json Object but in c#
string jsonResult = await response.Content.ReadAsStringAsync();
AccessTokenResponse result = JsonConvert.DeserializeObject<AccessTokenResponse>(jsonResult);
return result;
}
I hope this helps!
Homeslyce
After HOURS of research and tests and everything nothing worked, I was goign to flip that table. Your post saved my week, so far the best how to I’ve seen on the subject.
Microsoft should hire you!
For those wondering, you better start with Postman or any other API test application to test the 1st and 3rd section.
rajulshah
Hello @adamwallace3,
Can you please guide me as to how secure this is?
jhabek
Hi there, I am trying to embed report with PHP curl. I got everything working, but when I am trying to implement row level security I got stuck.
First I get access token (this works):
$curl1 = curl_init(); curl_setopt_array($curl1, array(CURLOPT_URL => "https://login.windows.net/common/oauth2/token", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => array( 'grant_type' => 'password', 'scope' => 'openid', 'resource' => 'https://analysis.windows.net/powerbi/api', 'client_id' => '0aa12345-1234-1234-1234-123412341234', // registered App ApplicationID 'username' => 'name@domain.com', // your Power BI Pro account, e.g. john.doe@yourdomain.com 'password' => 'mysecretpassword' // password for above user ) )); $tokenResponse = curl_exec($curl1); $tokenError = curl_error($curl1); curl_close($curl1); $tokenResult = json_decode($tokenResponse, true); $token = $tokenResult["access_token"]; $ embeddedToken = "Portador". ''. $ token;
Con este token de acceso, debería poder crear un token de inserción con RLS para cada usuario, PERO no funciona:
$curl3 = curl_init(); curl_setopt($curl3, CURLOPT_URL, 'https://api.powerbi.com/v1.0/myorg/groups/'.$group_Id.'/reports/'.$report_ID.'/GenerateToken'); curl_setopt($curl3, CURLOPT_RETURNTRANSFER, TRUE); //curl_setopt($curl3, CURLOPT_SSL_VERIFYPEER, false); //Might be required for https curl_setopt($curl3, CURLOPT_ENCODING, ""); curl_setopt($curl3, CURLOPT_MAXREDIRS, 10); curl_setopt($curl3, CURLOPT_TIMEOUT, 30); curl_setopt($curl3, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($curl3, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt ($curl3, CURLOPT_HTTPHEADER,array( 'Authorization: '.$embeddedToken, 'Content-Type:application/json; charset=utf-8', 'Accept:application/json', "accessLevel: View", "username: userOne", "roles: Tenant", "datasets: 12345678-1234-1234-1234-123123123" )); $RLStokenResponse = curl_exec($curl3); $RLStokenError = curl_error($curl3); curl_close($curl3); if ($RLStokenError) { echo "cURL Error #:" . $RLStokenError; } else { $RLStokenResult = json_decode($RLStokenResponse, true); $RLStoken = $RLStokenResult["access_token"]; $RLSembeddedToken = "Bearer " . ' ' . $RLStoken; }
Esta solicitud devuelve un error. ¿Podría decirme qué estoy haciendo mal?
franck_axires
¡Genial, gracias por compartir!
irfanharun
Hola, he podido completar los primeros 4 pasos en Postman.
Sin embargo, al probar el código de inserción en Microsoft Power BI Embedded Playground, sigo recibiendo el siguiente error:
> Json Object { "message": "LoadReportFailed", "detailedMessage": "Fail to initialize - Could not resolve cluster", "errorCode": "403", "level": 6, "technicalDetails": { "requestId": "57679585-022b-4871-ae6d-bb722d4a07cc" } }
Además, al probar la configuración HTML alternativa proporcionada en el PASO 5, de nuevo sigo recibiendo el error 403 que dice: «OBTENER https://wabi-india-west-redirect.analysis.windows.net/powerbi/globalservice/v201606/clusterdetails 403 (Prohibido) «
Por favor ayuda. He estado tratando de hacer que esto funcione durante más de una semana.
d_u_a
@ adamwallace3 Estoy enviando una solicitud de publicación con Me gusta en su primer paso. Pero obteniendo este error:
«error»: «invalid_request»,
«error_description»: «AADSTS90014: El cuerpo de la solicitud debe contener el siguiente parámetro: ‘grant_type’. r
Mi tipo de aplicación es web / api en azul. ¿Existe una solución para solucionar este problema de tipo de concesión?
miliu99
En respuesta a d_u_a
Obtienes este error «invalid_request» probablemente porque simplemente copiaste / pegaste datos: {} en el cuerpo sin procesar. Recibí el mismo error cuando lo hice, pero lo hice funcionar copiando solo los pares clave / valor dentro de los corchetes y pegándolos en los datos del formulario usando Bulk Edit (por supuesto, ingrese sus credenciales).
ezekielvp
En respuesta a d_u_a
@d_u_a escribió:
@ adamwallace3 Estoy enviando una solicitud de publicación con Me gusta en su primer paso. Pero obteniendo este error:
«error»: «invalid_request»,
«error_description»: «AADSTS90014: El cuerpo de la solicitud debe contener el siguiente parámetro: ‘grant_type’. rMi tipo de aplicación es web / api en azul. ¿Existe una solución para solucionar este problema de tipo de concesión?
Solía tener ese mensaje de error. Intenté usar cartero e ir al cuerpo y asegurarme de que eligió los datos del formulario y proporcionó la clave / valor necesario para la solicitud y todo debería funcionar
d_u_a
@ adamwallace3 Estoy enviando una solicitud de publicación con Me gusta en su primer paso. Pero obteniendo este error:
«error»: «invalid_request»,
«error_description»: «AADSTS90014: El cuerpo de la solicitud debe contener el siguiente parámetro: ‘grant_type’. r
Mi tipo de aplicación es web / api en azul. ¿Existe una solución para solucionar este problema de tipo de concesión?
aaco
Hola,
Al ejecutar el paso 4 en Postman (agregando el token de autorización en los encabezados y los datos en el cuerpo), aparece el siguiente error:
{
«error»: {
«código»: «»,
«message»: «El tipo de medio de la entidad de solicitud ‘multipart / form-data’ no es compatible con este recurso».
}
}
Además, cuando ejecuto el paso 5 en Chrome, aparece este mensaje de error:
OBTENGA https://wabi-north-europe-redirect.analysis.windows.net/metadata/cluster 403 (Prohibido)
Desde el paso 1 al paso 3, todo funciona como se describe. ¿Alguien más recibe el mismo mensaje de error? ¿Alguna idea de cómo solucionarlo o de dónde debería provenir?
Muchas gracias
aaco
En respuesta a aaco
Entonces, descubrí que no estaba usando la opción Body> raw> JSON (application / json) en Postman. Ahora lo hago pero obtengo un error diferente:
{
«error»: {
«code»: «No autorizado»,
«mensaje»: «Informe.Read.Todo el conjunto de datos.Read.Todo»
}
}
Para obtener información, los pasos 1 a 3 aún están bien y los permisos en el lado del registro de la aplicación de Azure para el ‘Servicio Power BI’ están todos configurados en ‘DELEGADO’ (19 en total).
Gracias de nuevo.
skizofre3e
En respuesta a aaco
@aaco ¿Encontraste el origen de este problema, por favor?
Ashleymartin
El paso 4 no me funciona. Pude obtener el token de acceso en el paso 2 y luego pude ejecutar el paso 3. Para el paso 4, ingresé la información del encabezado en el cartero debajo del encabezado y la información de datos debajo del cuerpo, pero recibo este error:
{
«error»: {
«código»: «BadRequest»,
«message»: «Solicitud incorrecta»,
«detalles»: [
{
«message»: «Unexpected character encountered while parsing number: W. Path », line 1, position 6.»,
«target»: «request»
}
]
}
}
]
}
}
¿Alguien más está experimentando esto o conoce alguna forma de solucionarlo? También como referencia estoy haciendo un servidor-web y he agregado el secreto del cliente en el primer paso, no estoy seguro de si necesitaría agregar algo en este cuarto paso también o si hay otra razón por la que muestra este error.
zachmiller
En respuesta a Ashleymartin
@ashleymartin La sección «data = {}» del paso 4 debe colocarse en la pestaña «Cuerpo» de Postman. Puede hacer clic en el botón de opción «sin procesar» para poder pegarlo directamente. Los encabezados también van en la pestaña de encabezados. Aparte de eso, asegúrese de que el token de acceso que tiene no esté vencido. Desde allí, puede usar el token de inserción donde lo considere apropiado.
matthewgouws
En respuesta a Ashleymartin
Hola,
¿Conseguiste encontrar una solución al error que recibías en el paso 4 de esta guía?
Saludos,
Mate
matthewgouws
En respuesta a Ashleymartin
Hola,
¿Encontró la solución al error que estaba obteniendo en el Paso 4?
¡Gracias por adelantado!
azulcore
Todos los pasos funcionan excepto el último. Ingresé todos los valores en https://microsoft.github.io/PowerBI-JavaScript/demo y funciona bien. Pero usar su código html al final solo da una página en blanco, ¿alguna idea? Uso clientid y clientsecret si eso marca la diferencia