Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Embed Power BI in ISV application (New Embed Model)

In my old post I described the fundamentals of Power BI Embedded which enables ISV developers to integrate Power BI report in their applications.
Power BI Embedded is one of the Azure services (not in Power BI license), and meets the several needs for ISV including : integrating the existing authentication method in ISV application, not needing Power BI license for application users, data separation for each tenant (same report, but different data), etc.

As you know, now the Power BI Premium is released (reached to GA), and new embed flow for ISV is released and is integrated by Power BI license (not Azure service).
If you're not familiar, please see the following team blog's announcement in the past.

Power BI blog "Microsoft accelerates modern BI adoption with Power BI Premium" (May 3, 2017)

... With Power BI Premium we’re also advancing how Power BI content is embedded in apps created by customers, partners and the broad developer community. As part of the new offering we are converging Power BI Embedded with the Power BI service to deliver one API surface, a consistent set of capabilities and access to the latest features. Moving forward we encourage those interested in embedding Power BI in their apps to start with Power BI Desktop and move to deployment with Power BI Premium. Existing apps built on Power BI Embedded will continue to be supported. ...

This new consistent experience unlocks Power BI for all ISVs, and all Power BI capabilities such as DirectQuery, streaming, report edit, and more data sources can be supported in ISV application.

In this post I show you this new embed flow for ISV developers and other broad developers.

Note : You can maintain your existing Power BI Embedded services in Azure, but you must remember that you cannot create the new one. (Use the new Power BI embed flow if you create the new one.)

Create pbix file with Power BI Desktop

Same as Power BI Embedded (deprecated) in Azure, first you define the data source and reports to be embedded with your Power BI Desktop. (There’s no need to programming for building reports.)
In this post, I don’t explain the details about how to use the Power BI Desktop, and see the tutorial document (official document) for the usage.

When you have finished, please save the report in your local disk as pbix file (.pbix file).

Note : You can also download the sample of "Retail Analysis PBIX".

Create Power BI workspace and import pbix

Next you create the Power BI workspace (app workspace). Each workspaces will deliver the report, data source, and other artifacts for each customers.
You will need a user that has a pro license in order to create an app workspace within Power BI, and this task is done by UI (Power BI services) or rest api.

Note : The app workspace is equal to the "group". When you use rest api, please add a group.

When you use Power BI services (Web UI), please select "Workspaces" menu and push "Create app workspace". (Then the following form will be displayed.)
When you create your app workspace in your real production application, please turn on "premium" (see below) and assign the resource pool. By doing this, the report is not consumed by the personal license, but the resource-based license is used with flexible Power BI Premium capacity.

After you've created the customer's app workspace, please get the workspace id (so called "group id").
You can copy this value (group id) from the url (address) of the workspace in Power BI services, or you can get with rest api as follows.

Note : The following authorization Token in the HTTP header is the master account's user token i.e, Azure AD token. (See my old post for the flow of getting the Power BI user token.)
Later I explain about the token.

GET https://api.powerbi.com/v1.0/myorg/groups
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal

{
  "@odata.context": "http://df-app-scus-redirect.analysis.windows.net/v1.0/myorg/$metadata#groups",
  "value": [
    {
      "id": "a4781858-f3ef-47c2-80a9-fa14845c833b",
      "isReadOnly": false,
      "name": "myws01"
    },
    ...
    
  ]
}

Next you import your pbix (Power BI file) into this generated workspace. This task also can be done by rest api or UI. (Push "publish" in Power BI Desktop as the following picture.)

After you've imported Power BI file, please get the imported dataset id, report id, and report embed url.
The following HTTP request retrieves the imported dataset id. (Please change a4781858-f3ef-47c2-80a9-fa14845c833b to your group id.)

GET https://api.powerbi.com/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/datasets
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal

{
  "@odata.context": "http://df-app-scus-redirect.analysis.windows.net/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/$metadata#datasets",
  "value": [
    {
      "id": "44a12ee1-8da7-4383-a2cf-89129ef6e1a7",
      "name": "Retail Analysis Sample",
      "addRowsAPIEnabled": false,
      "configuredBy": "[email protected]"
    }
  ]
}

The following retrieves the report id, as well as report embed url (embedUrl) which is used for the embedding report.

GET https://api.powerbi.com/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/reports
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal

{
  "@odata.context": "http://df-app-scus-redirect.analysis.windows.net/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/$metadata#reports",
  "value": [
    {
      "id": "b21f4f90-e364-4b4c-9281-c5db87cdf3a5",
      "modelId": 0,
      "name": "Retail Analysis Sample",
      "webUrl": "https://app.powerbi.com/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/reports/b21f4f90-e364-4b4c-9281-c5db87cdf3a5",
      "embedUrl": "https://app.powerbi.com/reportEmbed?reportId=b21f4f90-e364-4b4c-9281-c5db87cdf3a5&groupId=a4781858-f3ef-47c2-80a9-fa14845c833b",
      "isOwnedByMe": true,
      "isOriginalPbixReport": false,
      "datasetId": "44a12ee1-8da7-4383-a2cf-89129ef6e1a7"
    }
  ]
}

Data source connectivity and multi-tenancy of data

Although almost all the artifacts in pbix file are imported into your workspace, the credential for the data source is not imported because of security reasons. As a result, if you’re using DirectQuery mode, the embedded report cannot be shown correctly. (On the other hand, if you’re using Import mode, you can view the report using the existing imported data.)

For ISV applications (SaaS applications, etc), the separation of data is also concerns. The customer A and B will view the different data in ISV's application.

In such a case, you can set and change the connection string or credentials using rest api.

First you can get the data source id and gateway id by the following HTTP request.  (In this example, we assume that the type of data source is SQL Server.)
Note that the following "id" in HTTP response is the data source id.

GET https://api.powerbi.com/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/datasets/44a12ee1-8da7-4383-a2cf-89129ef6e1a7/Default.GetBoundGatewayDataSources
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal

{
  "@odata.context": "http://df-app-scus-redirect.analysis.windows.net/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/$metadata#gatewayDatasources",
  "value": [
    {
      "id": "2a0bca27-a496-450c-80e0-05790ad8875f",
      "gatewayId": "d52ba684-afa8-484d-b5d5-790842b6ab9f",
      "datasourceType": "Sql",
      "connectionDetails": "{"server":"server01.database.windows.net","database":"db01"}"
    }
  ]
}

Using gateway id and data source id, you can set (or change) the credential of this data source as follows.

PATCH https://api.powerbi.com/v1.0/myorg/gateways/d52ba684-afa8-484d-b5d5-790842b6ab9f/datasources/2a0bca27-a496-450c-80e0-05790ad8875f
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
Content-Type: application/json; charset=utf-8

{
  "credentialType": "Basic",
  "basicCredentials": {
    "username": "demouser",
    "password": "pass@word1"
  }
}
HTTP/1.1 200 OK

The following changes the connection string for the data source via rest api. (The data source id also changes when you change the connection string.)

POST https://api.powerbi.com/v1.0/myorg/groups/a4781858-f3ef-47c2-80a9-fa14845c833b/datasets/44a12ee1-8da7-4383-a2cf-89129ef6e1a7/Default.SetAllConnections
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
Content-Type: application/json; charset=utf-8

{
  "connectionString": "data source=tsmatsuz-server2.database.windows.net;initial catalog=db02;persist security info=True;encrypt=True;trustservercertificate=False"
}
HTTP/1.1 200 OK

The idea of AuthN / AuthZ for new embed model

Before embedding your report in your application, you must learn about the idea of AuthN / AuthZ in the new embed model.

In provisioning phase (creating workspace, importing pbix, setting credentials, etc), it's okay to use the Azure AD user's (master account's) access token for calling api, because it's not exposed to the end users. (The only admin does these management tasks.)

How about viewing the embedded report ? (Of course, AuthN / AuthZ must be needed for viewing report.)
The user in ISV application is not necessarily Power BI users or Azure AD users, then it's not good to use the Azure AD access token directly. If you were to use the master account's user token for all end user's reports, the token will be abused for other reports that the user doesn't have permission.

In this case, you can get Power BI embed token in the backend (in the server-side) with the following HTTP request, and your application can use this token for the user-side processing securely. This signed token is for some specific user's operation (viewing some report, etc) and if the user needs other operations, the new token must be issued in the server side. (The token expires in one hour.)

POST https://api.powerbi.com/v1.0/myorg/groups/{group id}/reports/{report id}/GenerateToken
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
Content-Type: application/json; charset=utf-8

{
  "accessLevel": "View",
  "allowSaveAs": "false"
}
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal

{
  "@odata.context": "http://df-app-scus-redirect.analysis.windows.net/v1.0/myorg/groups/{group id}/$metadata#Microsoft.PowerBI.ServiceContracts.Api.V1.GenerateTokenResponse",
  "token": "H4sIAAAAAA...",
  "tokenId": "63c8d0ea-800d-462c-9906-22a4567f276f",
  "expiration": "2017-07-15T08:29:29Z"
}

As you can see, the Azure AD access token must be provided in the request HTTP above, and this Azure AD access token must be issued in your application's backend (without interactive login UI). That is, this type of access token must be app-only token. (See my old post for the OAuth flow of app-only access token.)
But currently Power BI doesn't support app-only token. Therefore instead you must now use the user access token with non-interactive sign-in. For example, the following is the OAuth password grant flow without interactive sign-in. (Note that this password grant flow is not recommended in the usual cases, because it's not secure and the several capabilities like 2FA cannot be supported.)

POST https://login.microsoftonline.com/common/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=password
&client_id=dede99a5-ed89-4881-90a4-4564dae562f7
&client_secret=P4GmxWa...
&username=tsmatsuz%40test.onmicrosoft.com
&password=pass%40word1
&resource=https%3A%2F%2Fanalysis.windows.net%2Fpowerbi%2Fapi
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "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",
  "expires_in": "3599",
  "ext_expires_in": "0",
  "expires_on": "1500032600",
  "not_before": "1500028700",
  "resource": "https://analysis.windows.net/powerbi/api",
  "access_token": "eyJ0eXAiOi...",
  "refresh_token": "AQABAAAAAA..."
}

Note : With Power BI Embedded (deprecated) in Azure, you could use app key in Azure Portal for creating embed token.

If the user needs to edit the report, please send the following HTTP request in the server side with "Edit" as "accessLevel". In the same way, you can set "Create" as "accessLevel" for enabling users to create new reports in your embedded Power BI.

POST https://api.powerbi.com/v1.0/myorg/groups/{group id}/reports/{report id}/GenerateToken
Accept: application/json
Authorization: Bearer eyJ0eXAiOi...
Content-Type: application/json; charset=utf-8

{
  "accessLevel": "Edit",
  "allowSaveAs": "false"
}

Note : The RLS (Row-Level Security) is not supported now (on the roadmap).

Hosting (embedding) reports in your web page

Now you can embed your Power BI report in your application with Power BI JavaScript API.

Let's see the following javascript example.
Please set your embed url (txtEmbedUrl) and report id (txtEmbedReportId) which are previously retrieved by the rest api. The access token (txtAccessToken) is the embed token for report viewing (not Azure AD access token).



  Test

Power BI Embed test

This HTML will display the following embedded report (View Mode).

In the backend of javascript api, the iframe is inserted in your web page, and some attributes (including embed token) are passed by the inter-frame communications. (See the following postMessage().)
The following sample code displays the same result without Power BI JavaScript API. (Please use JavaScript API for your production. This is just the sample for your understanding.)

Note : The uid (uniqueId) is the random string.



  Test without Power BI JavaScript API

Power BI Embed test

With the new embed experience, you can easily enable application users to edit embedded reports as follows. (You can also enable users to create new reports in your embed experience.)
You must remember that this embed token must be for editing (i.e, "accessLevel": "Edit").



  Test

Power BI Embed test

Using Javascript API, you can also interact with the embedded report, like filtering, reload, changing page, visual settings, etc.
You can see the following github example for these operations with javascript sample code.

[Github] Microsoft Power BI – Report Embed Sample
https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html

Share the post

Embed Power BI in ISV application (New Embed Model)

×

Subscribe to Msdn Blogs | Get The Latest Information, Insights, Announcements, And News From Microsoft Experts And Developers In The Msdn Blogs.

Get updates delivered right to your inbox!

Thank you for your subscription

×