Share via


チュートリアル: 顧客向けのアプリケーションに 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 リポジトリから入手できます。

前提条件

リソース

このチュートリアルでは、次のものを使います。

Method

顧客向け埋め込みソリューションに Power BI コンテンツを埋め込むには、以下の手順のようにします。

  1. Microsoft Entra アプリとサービス プリンシパル を構成します

  2. 埋め込みパラメーター値を取得します

  3. 必要な NuGet パッケージを追加します

  4. サーバー側の認証を有効にします

  5. アプリのクライアント側をビルドします

  6. アプリケーションを実行します

手順 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" とも呼ばれます) を取得するには、これらの手順に従います。

  1. Microsoft Azure にログインします。

  2. [アプリの登録] を検索し、 [アプリの登録] リンクを選択します。

  3. Power BI コンテンツを埋め込むために使用する Microsoft Entra アプリを選択します。

  4. [概要] セクションで、 [アプリケーション (クライアント) ID] の GUID をコピーします。

クライアント シークレット

クライアント シークレットを取得するには、これらの手順に従います。

  1. Microsoft Azure にログインします。

  2. [アプリの登録] を検索し、 [アプリの登録] リンクを選択します。

  3. Power BI コンテンツを埋め込むために使用する Microsoft Entra アプリを選択します。

  4. [管理] で、[証明書とシークレット] を選択します。

  5. [クライアント シークレット] で、 [新しいクライアント シークレット] を選択します。

  6. [クライアント シークレットの追加] ポップアップ ウィンドウで、アプリケーション シークレットの説明を入力し、アプリケーション シークレットの有効期限を選択し、 [追加] を選択します。

  7. [クライアント シークレット] セクションで、新しく作成されたアプリケーション シークレットの [値] 列にある文字列をコピーします。 そのクライアント シークレットの値が "クライアント ID" です。

注意

クライアント シークレットの値が最初に表示されときに、必ずそれをコピーしてください。 このページから移動すると、クライアント シークレットは表示されなくなり、その値を取得できなくなります。

ワークスペース ID

ワークスペース ID の GUID を取得するには、これらの手順に従います。

  1. Power BI サービスにサインインします。

  2. 埋め込むレポートを開きます。

  3. URL から GUID をコピーします。 GUID は /groups//reports/ の間にある数値です。

    A screenshot showing workspace ID GUID in the Power B I service U R L

Note

プログラムでワークスペース ID を取得するには、Get Groups API を使用します。

レポート ID

テナント ID GUID を取得するには、次の手順に従います。

  1. Power BI サービスにサインインします。

  2. 埋め込むレポートを開きます。

  3. URL から GUID をコピーします。 GUID は /reports//ReportSection の間にある数値です。

    A screenshot showing report ID GUID in the Power B I service U R L

Note

プログラムでレポート 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 のコードでは、次のいくつかの重要な処理を行います。

  1. AddMicrosoftWebAppCallsWebApi を呼び出して、アクセス トークン (Microsoft Entra トークン) を取得するように Microsoft 認証ライブラリを構成します。
  2. AddInMemoryTokenCaches を呼び出して、バックグラウンドでアクセス トークンをキャッシュしてトークンを更新するために Microsoft 認証ライブラリで使われるトークン キャッシュを構成します。
  3. 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 などのより安全なツールを使って機密情報をセキュリティ保護することを検討してください。

  1. プロジェクトで、新しいファイルを作成し、appsettings.json という名前を付けます。

  2. 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": "*"
    }
    
  3. 手順 2 - 埋め込みパラメーター値を取得する」で取得した埋め込みパラメーター値を入力します。

注意

前のコードでは、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 アプリのアクセス許可を変更する」を参照してください。

  1. アプリのプロジェクトで、Services というタイトルの新しいフォルダーを作成します。

  2. その Services フォルダー内に、PowerBiServiceApi.cs というタイトルの新しいファイルを作成します。

  3. 以下のコードを 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 ファイル作成します。

  1. View/Home フォルダーに、Embed.cshtml というファイルを作成します。

  2. 次のコードをその 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.Allmodels.TokenType.Aadmodels.ViewMode.View などの構成値を設定するために使用されます。

powerbi.embed 関数では、models 構成オブジェクトを使用してレポートを埋め込みます。

  1. wwwroot/js フォルダー内に、embed.js というファイルを作成します。

  2. 次のコードをその 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 を使用してアプリを強化することができます。

重要

無料の埋め込み試用版トークンを開発に使用した場合は、運用環境用の容量を購入する必要があります。 容量を購入するまで、埋め込みレポートの上部に "無料試用版バージョン" バナーが引き続き表示されます。

アプリの準備ができたら、埋め込みアプリを運用環境に移行することができます。