チュートリアル: 顧客向けのアプリケーションに Power BI レポートを埋め込む
このチュートリアルでは、"顧客向け埋め込み" ("アプリ所有データ" とも呼ばれます) ソリューションの一部として、Power BI レポートを .NET 5.0 アプリケーションに埋め込む方法について学習します。 顧客向け埋め込みソリューションでは、アプリのユーザーが Power BI にサインインしたり、Power BI ライセンスを持つ必要はありません。
このチュートリアルでは、埋め込み方法を学習します。
- Power BI レポート。
- 顧客向け埋め込みアプリ内。
- "サービス プリンシパル" の使用。
- .NET 5.0 の使用。
Microsoft.Identity.Web
ライブラリで (このライブラリは .Net Core でもサポートされています)。
注意
このチュートリアルで使用される完全なソリューションは、DOTNET5-AppOwnsData-Tutorial GitHub リポジトリから入手できます。
前提条件
Power BI Pro または Premium Per User (PPU) のライセンス
レポートを含む Power BI ワークスペース
.NET Core 5 モデル ビュー コントローラー (MVC) アプリ
統合開発環境 (IDE)。 次のいずれかの IDE をお勧めします。
リソース
このチュートリアルでは、次のものを使います。
Power BI REST Reports API。URL を埋め込み、埋め込みトークンを取得するため。
Power BI 埋め込み分析の Client API。レポートを埋め込むため。
Method
顧客向け埋め込みソリューションに Power BI コンテンツを埋め込むには、以下の手順のようにします。
手順 1 - Microsoft Entra アプリとサービス プリンシパルを構成する
このチュートリアルでは、サービス プリンシパルを使って、Microsoft Entra ID に対する Web アプリの認証を行います。 また、Microsoft Entra トークンを生成できるようにする Microsoft Entra アプリも必要です。 Microsoft Entra トークンを使うことにより、Web アプリで Power BI REST API を呼び出し、Power BI の項目 (レポート、ダッシュボード、タイルなど) を埋め込むことができます。
サービス プリンシパルの手順に従って、Microsoft Entra アプリを作成し、アプリのサービス プリンシパルが Power BI コンテンツと連携できるようにします。
手順 2 - 埋め込みパラメーター値を取得する
レポートを埋め込むには、次の値が必要です。
ドメインとテナント ID
ドメインやテナント ID が不明な場合は、Microsoft Entra テナント ID とプライマリ ドメイン名の検索に関する説明を参照してください。
Note
別のテナントのユーザー (ゲスト ユーザー) 用にコンテンツを埋め込むには、authorityUri
パラメーターを調整する必要があります。
クライアント ID
クライアント ID GUID ("アプリケーション ID" とも呼ばれます) を取得するには、これらの手順に従います。
Microsoft Azure にログインします。
[アプリの登録] を検索し、 [アプリの登録] リンクを選択します。
Power BI コンテンツを埋め込むために使用する Microsoft Entra アプリを選択します。
[概要] セクションで、 [アプリケーション (クライアント) ID] の GUID をコピーします。
クライアント シークレット
クライアント シークレットを取得するには、これらの手順に従います。
Microsoft Azure にログインします。
[アプリの登録] を検索し、 [アプリの登録] リンクを選択します。
Power BI コンテンツを埋め込むために使用する Microsoft Entra アプリを選択します。
[管理] で、[証明書とシークレット] を選択します。
[クライアント シークレット] で、 [新しいクライアント シークレット] を選択します。
[クライアント シークレットの追加] ポップアップ ウィンドウで、アプリケーション シークレットの説明を入力し、アプリケーション シークレットの有効期限を選択し、 [追加] を選択します。
[クライアント シークレット] セクションで、新しく作成されたアプリケーション シークレットの [値] 列にある文字列をコピーします。 そのクライアント シークレットの値が "クライアント ID" です。
注意
クライアント シークレットの値が最初に表示されときに、必ずそれをコピーしてください。 このページから移動すると、クライアント シークレットは表示されなくなり、その値を取得できなくなります。
ワークスペース ID
ワークスペース ID の GUID を取得するには、これらの手順に従います。
Power BI サービスにサインインします。
埋め込むレポートを開きます。
URL から GUID をコピーします。 GUID は /groups/ と /reports/ の間にある数値です。
Note
プログラムでワークスペース ID を取得するには、Get Groups API を使用します。
レポート ID
テナント ID GUID を取得するには、次の手順に従います。
Power BI サービスにサインインします。
埋め込むレポートを開きます。
URL から GUID をコピーします。 GUID は /reports/ と /ReportSection の間にある数値です。
注意
プログラムでレポート ID を取得するには、Get Reports In Group API を使用します。
手順 3 - 必要な NuGet パッケージを追加する
作業を開始する前に、Microsoft.Identity.Web
および Microsoft.PowerBI.Api
NuGet パッケージをアプリに追加する必要があります。
必要な NuGet パッケージをアプリに追加します。
VS Code でターミナルを開き、次のコードを入力します。
Visual Studio で、[ツール]>[NuGet パッケージ マネージャー]>[パッケージ マネージャー コンソール] に移動し、次のコードを入力します。
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Identity.Web.UI
dotnet add package Microsoft.PowerBI.Api
手順 4 - サーバー側の認証を有効にする
以下の表のファイルを作成または変更して、アプリでサーバー側の認証を有効にします。
ファイル | 使用 |
---|---|
Startup.cs | Microsoft.Identity.Web 認証サービスを初期化する |
appsettings.json | 認証の詳細を構成する |
PowerBiServiceApi.cs | Microsoft Entra トークンと埋め込みメタデータを取得する |
HomeController.cs | モデルとして埋め込みデータをビューに渡す |
Microsoft.Identity.Web
をサポートするようにスタートアップ ファイルを構成する
Startup.cs 内のコードを変更し、Microsoft.Identity.Web
によって提供される認証サービスを適切に初期化します。
次のコードをアプリの Startup.cs ファイルに追加します。
注意
ConfigureServices
のコードでは、次のいくつかの重要な処理を行います。
AddMicrosoftWebAppCallsWebApi
を呼び出して、アクセス トークン (Microsoft Entra トークン) を取得するように Microsoft 認証ライブラリを構成します。AddInMemoryTokenCaches
を呼び出して、バックグラウンドでアクセス トークンをキャッシュしてトークンを更新するために Microsoft 認証ライブラリで使われるトークン キャッシュを構成します。services.AddScoped(typeof(PowerBiServiceApi))
を呼び出し、依存関係の挿入を使用して他のクラスに追加できるサービス クラスとしてPowerBiServiceApi
クラスを構成します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using AppOwnsData.Services;
namespace AppOwnsData
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddScoped(typeof(PowerBiServiceApi));
services.AddControllersWithViews(options => {
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages()
.AddMicrosoftIdentityUI();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You might want to change this for production scenarios. See https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
}
認証の詳細ファイルを作成する
このチュートリアルの appsettings.json ファイルには、''クライアント ID'' や ''クライアント シークレット'' などの機密情報が含まれています。 セキュリティ上の理由から、この情報を設定ファイルに保持することはお勧めしません。 アプリケーションに埋め込む場合は、Azure Key Vault などのより安全なツールを使って機密情報をセキュリティ保護することを検討してください。
プロジェクトで、新しいファイルを作成し、appsettings.json という名前を付けます。
appsettings.json に以下のコードを追加します。
{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "yourtenant.onMicrosoft.com", "TenantId": "", "ClientId": "", "ClientSecret": "", "CallbackPath": "/signin-oidc", "SignedOutCallbackPath": "/signout-callback-oidc" }, "PowerBi": { "ServiceRootUrl": "https://api.powerbi.com/" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" }
「手順 2 - 埋め込みパラメーター値を取得する」で取得した埋め込みパラメーター値を入力します。
Domain
- ドメインとテナント IDTenantId
- ドメインとテナント IDClientId
- クライアント IDClientSecret
- クライアント シークレット
注意
前のコードでは、Power BI サービスのベース URL を追跡するために、PowerBi:ServiceRootUrl
パラメーターがカスタム構成値として追加されています。 Microsoft のパブリック クラウドの Power BI サービスに対してプログラミングする場合、URL は https://api.powerbi.com/
になります。 一方、政府機関向けクラウドなどの他のクラウドでは、Power BI サービスのルート URL が異なります。 したがって、このカスタム構成値は、必要に応じて変更できるように、プロジェクト構成値として格納されます。
Microsoft Entra アクセス トークンを取得し、Power BI サービスを呼び出す
レポートやダッシュボードなどの Power BI コンテンツを埋め込むには、アプリで Microsoft Entra トークンを取得する必要があります。 トークンを取得するには、構成オブジェクトが必要になります。
このセクションのコードでは、.NET Core の依存関係の挿入パターンを使用します。 クラスでサービスを使用する必要がある場合は、そのサービスのコンストラクター パラメーターを追加できます。 実行時にサービス インスタンスを渡す処理は、.NET Core ランタイムによって行われます。 この場合、コンストラクターにより IConfiguration
パラメーターを使って .NET Core 構成サービスのインスタンスが挿入され、それを使って appsettings.json から PowerBi:ServiceRootUrl
構成値が取得されます。 tokenAcquisition
という名前の ITokenAcquisition
パラメーターは、Microsoft.Identity.Web
ライブラリによって提供される Microsoft 認証サービスへの参照を保持します。 ITokenAcquisition
パラメーターは、Microsoft Entra ID からアクセス トークンを取得するために使われます。
RequiredScopes
フィールドは、Power BI サービス API によってサポートされる一連の委任されたアクセス許可を含む文字列配列を保持します。 アプリケーションで Microsoft Entra トークンを取得するためにネットワーク経由で呼び出しを行うときに、この委任されたアクセス許可のセットを渡すと、Microsoft Entra ID は送り返すアクセス トークンにそれらを含めることができます。
Note
''Microsoft Entra アプリ'' がご利用の Web アプリに必要なスコープで構成されていることをご確認ください。 詳細については、「Microsoft Entra アプリのアクセス許可を変更する」を参照してください。
アプリのプロジェクトで、Services というタイトルの新しいフォルダーを作成します。
その Services フォルダー内に、PowerBiServiceApi.cs というタイトルの新しいファイルを作成します。
以下のコードを PowerBiServiceApi.cs に追加します。
using System; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using Microsoft.Identity.Web; using Microsoft.Rest; using Microsoft.PowerBI.Api; using Microsoft.PowerBI.Api.Models; using Newtonsoft.Json; namespace AppOwnsData.Services { // A view model class to pass the data needed to embed a single report public class EmbeddedReportViewModel { public string Id; public string Name; public string EmbedUrl; public string Token; } public class PowerBiServiceApi { private ITokenAcquisition tokenAcquisition { get; } private string urlPowerBiServiceApiRoot { get; } public PowerBiServiceApi(IConfiguration configuration, ITokenAcquisition tokenAcquisition) { this.urlPowerBiServiceApiRoot = configuration["PowerBi:ServiceRootUrl"]; this.tokenAcquisition = tokenAcquisition; } public const string powerbiApiDefaultScope = "https://analysis.windows.net/powerbi/api/.default"; // A method to get the Azure AD token (also known as 'access token') public string GetAccessToken() { return this.tokenAcquisition.GetAccessTokenForAppAsync(powerbiApiDefaultScope).Result; } public PowerBIClient GetPowerBiClient() { var tokenCredentials = new TokenCredentials(GetAccessToken(), "Bearer"); return new PowerBIClient(new Uri(urlPowerBiServiceApiRoot), tokenCredentials); } public async Task<EmbeddedReportViewModel> GetReport(Guid WorkspaceId, Guid ReportId) { PowerBIClient pbiClient = GetPowerBiClient(); // Call the Power BI service API to get the embedding data. var report = await pbiClient.Reports.GetReportInGroupAsync(WorkspaceId, ReportId); // Generate a read-only embed token for the report. var datasetId = report.DatasetId; var tokenRequest = new GenerateTokenRequest(TokenAccessLevel.View, datasetId); var embedTokenResponse = await pbiClient.Reports.GenerateTokenAsync(WorkspaceId, ReportId, tokenRequest); var embedToken = embedTokenResponse.Token; // Return the report embedded data to caller. return new EmbeddedReportViewModel { Id = report.Id.ToString(), EmbedUrl = report.EmbedUrl, Name = report.Name, Token = embedToken }; } } }
HomeController.cs ファイルを変更する
このコード例では、依存関係の挿入を使って HomeController.cs ファイルを変更します。 前の手順に従って、ConfigureServices
メソッドで services.AddScoped
を呼び出すことで、PowerBiServiceApi
クラスをサービスとして構成しました。 このコードでコンストラクターに PowerBiServiceApi
パラメーターを追加すると、.NET Core ランタイムによって PowerBiServiceApi
インスタンスが作成されて、コンストラクターに渡されます。
Controllers フォルダーから HomeController.cs ファイルを開き、次のコードをそれに追加します。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using AppOwnsData.Models;
using AppOwnsData.Services;
namespace AppOwnsData.Controllers
{
[Authorize]
public class HomeController : Controller
{
private PowerBiServiceApi powerBiServiceApi;
public HomeController(PowerBiServiceApi powerBiServiceApi)
{
this.powerBiServiceApi = powerBiServiceApi;
}
[AllowAnonymous]
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> Embed() {
// Replace these two GUIDs with the workspace ID and report ID you recorded earlier.
Guid workspaceId = new Guid("11111111-1111-1111-1111-111111111111");
Guid reportId = new Guid("22222222-2222-2222-2222-222222222222");
var viewModel = await powerBiServiceApi.GetReport(workspaceId, reportId);
return View(viewModel);
}
[AllowAnonymous]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
手順 5 - アプリのクライアント側をビルドする
クライアント側の実装では、次の表の一覧で示すファイルを作成または変更する必要があります。
ファイル | 使用 |
---|---|
embed.js | クライアント側の JavaScript コードが含まれます |
Embed.cshtml | アプリのドキュメント オブジェクト モデル (DOM) と、レポートを埋め込むための DIV が含まれます |
埋め込みレポートのコンテナーを作成する
このチュートリアルでは、埋め込みレポートのコンテナーである div
要素と 3 つのスクリプトを含む、Embed.cshtml ファイル作成します。
View/Home フォルダーに、Embed.cshtml というファイルを作成します。
次のコードをその Embed.cshtml ファイルに追加します。
@model AppOwnsData.Services.EmbeddedReportViewModel; <div id="embed-container" style="height:800px;"></div> @section Scripts { <!-- powerbi.min.js is the JavaScript file that loads the client-side Power BI JavaScript API library. Make sure that you're working with the latest library version. You can check the latest library available in https://cdnjs.com/libraries/powerbi-client --> <script src="https://cdn.jsdelivr.net/npm/powerbi-client@2.18.0/dist/powerbi.min.js"></script> <!-- This script creates a JavaScript object named viewModel which is accessible to the JavaScript code in embed.js. --> <script> var viewModel = { reportId: "@Model.Id", embedUrl: "@Model.EmbedUrl", token: "@Model.Token" }; </script> <!-- This script specifies the location of the embed.js file --> <script src="~/js/embed.js"></script> }
クライアント側の JavaScript を追加してレポートを埋め込む
Power BI コンテンツを埋め込むには、構成オブジェクトを作成する必要があります。 構成オブジェクトの作成の詳細については、「レポートを埋め込む」を参照してください。
このチュートリアルでは、models
変数を使用するレポートを埋め込むための構成オブジェクトを含む embed.js という名前の JavaScript ファイルを作成します。
window['powerbi-client'].models
の呼び出しを使って models
を初期化できます。 models
変数は、models.Permissions.All
、models.TokenType.Aad
、models.ViewMode.View
などの構成値を設定するために使用されます。
powerbi.embed
関数では、models
構成オブジェクトを使用してレポートを埋め込みます。
wwwroot/js フォルダー内に、embed.js というファイルを作成します。
次のコードをその embed.js ファイルに追加します。
$(function () { // 1 - Get DOM object for the div that's the report container. var reportContainer = document.getElementById("embed-container"); // 2 - Get the report embedding data from the view model. var reportId = window.viewModel.reportId; var embedUrl = window.viewModel.embedUrl; var token = window.viewModel.token // 3 - Embed the report by using the Power BI JavaScript API. var models = window['powerbi-client'].models; var config = { type: 'report', id: reportId, embedUrl: embedUrl, accessToken: token, permissions: models.Permissions.All, tokenType: models.TokenType.Embed, viewMode: models.ViewMode.View, settings: { panes: { filters: { expanded: false, visible: true }, pageNavigation: { visible: false } } } }; // Embed the report and display it within the div container. var report = powerbi.embed(reportContainer, config); // 4 - Add logic to resize the embed container on a window resize event. var heightBuffer = 12; var newHeight = $(window).height() - ($("header").height() + heightBuffer); $("#embed-container").height(newHeight); $(window).resize(function () { var newHeight = $(window).height() - ($("header").height() + heightBuffer); $("#embed-container").height(newHeight); }); });
手順 6 - アプリケーションを実行する
前のすべての手順に従うと、アプリケーションを実行できる状態になります。 アプリケーションを実行し、Power BI レポートの埋め込み方法を試してみます。 Power BI 埋め込み分析のクライアント API を使い、クライアント側の API を使用してアプリを強化することができます。
重要
無料の埋め込み試用版トークンを開発に使用した場合は、運用環境用の容量を購入する必要があります。 容量を購入するまで、埋め込みレポートの上部に "無料試用版バージョン" バナーが引き続き表示されます。
アプリの準備ができたら、埋め込みアプリを運用環境に移行することができます。