共用方式為


使用 Power BI 內嵌開發可調整的多租用戶應用程式

本文說明如何開發多租用戶應用程式,以內嵌 Power BI 內容,同時達到最高層級的可擴縮性、效能和安全性。 藉由使用服務主體設定檔來設計和實作應用程式,您可以建立和管理由數以萬計客戶租用戶所組成的多租用戶解決方案,這些租用戶可將報告傳遞給超過 100,000 個使用者的對象。

服務主體設定檔是一項功能,可讓您更輕鬆地管理 Power BI 中的組織內容,並更有效率地使用您的容量。 不過,使用服務主體設定檔會增加應用程式設計的複雜性。 因此,只有在需要達到相當規模時,才應該使用它們。 當您有許多工作區和超過 1,000 個應用程式使用者時,建議您使用服務主體設定檔。

注意

使用服務主體設定檔的值會增加,因為您需要相應增加,且您需要達到最高層級的安全性和租用戶隔離。

您可以使用兩個不同的內嵌案例來達成 Power BI 內嵌:為您的組織內嵌和為您的組織內嵌

當應用程式對象包含內部使用者時,就會套用為您的組織內嵌案例。 內部使用者具有組織帳戶,且必須使用 Microsoft Entra ID 進行驗證 (先前稱為 Azure Active Directory)。 在這個案例中,Power BI 為軟體即服務 (SaaS)。 它有時稱為使用者擁有資料

當應用程式對象包含外部使用者時,就會套用為您的組織內嵌案例。 應用程式負責驗證使用者。 為了存取 Power BI 內容,應用程式依賴於內嵌身分識別 (Microsoft Entra 服務主體或主要使用者帳戶) 向 Microsoft Entra 進行驗證。 在此案例中,Power BI 為平台即服務 (PaaS)。 它有時稱為應用程式擁有資料

注意

請務必了解服務主體設定檔功能的設計目的是要與為您的客戶內嵌案例搭配使用。 這是因為此案例可讓 ISV 和企業組織能夠大規模地內嵌大量使用者,以及大量的客戶租用戶。

多租用戶應用程式開發

如果您熟悉 Microsoft Entra,租用戶一詞可能會讓您聯想到 Microsoft Entra 租用戶。 不過,在建置內嵌 Power BI 內容的多租用戶解決方案內容中,租用戶的概念會有所不同。 在此內容中,會代表應用程式使用為您的客戶內嵌案例內嵌 Power BI 內容的每個客戶建立客戶租用戶。 您通常會藉由建立單一 Power BI 工作區來佈建每個客戶租用戶。

若要建立可調整的多租用戶解決方案,您必須能夠自動建立新的客戶租用戶。 佈建新的客戶租用戶通常牽涉到撰寫使用 Power BI REST API 來建立新 Power BI 工作區的程式碼、匯入 Power BI Desktop (.pbix) 檔案、更新資料來源參數、設定資料來源認證,以及設定排程的語意模型重新整理來建立語意模型 (先前稱為資料集)。 下圖顯示如何將 Power BI 項目,例如報告和語意模型新增至工作區,以設定客戶租用戶。

圖表顯示三個租用戶的設定。每個租用戶都有自己的資料來源和工作區。

當您開發使用為您的客戶內嵌案例的應用程式時,可以使用主要使用者帳戶或服務主體的內嵌身分識別來發出 Power BI REST API 呼叫。 我們建議針對生產應用程式使用服務主體。 它提供最高的安全性,因此它是 Microsoft Entra 所建議的方法。 此外,也支援更佳的自動化和規模,而且減少管理額外負荷。 不過,它需要 Power BI 系統管理員權限才能設定和管理

藉由使用服務主體,您可以避免與主要使用者帳戶相關聯的常見問題,例如使用者必須使用多重要素驗證 (MFA) 登入的環境中發生驗證錯誤。 使用服務主體也與使用 PaaS 思維而非 SaaS 思維來內嵌 Power BI 內容的為您的客戶內嵌案例概念一致。

1,000 個工作區限制

當您設計實作為您的客戶內嵌案例的多租用戶環境時,請務必考慮內嵌身分識別無法授與超過 1,000 個工作區的存取權。 Power BI 服務會施加這項限制,以確保在發出 REST API 呼叫時有良好的效能。 這項限制的原因與 Power BI 如何維護每個身分識別的安全性相關中繼資料有關。

Power BI 會使用中繼資料來追蹤身分識別可以存取的工作區和工作區項目。 實際上,Power BI 必須為其授權子系統中的每個身分識別維護個別的存取控制清單 (ACL)。 當身分識別發出 REST API 呼叫以存取工作區時,Power BI 必須針對身分識別的 ACL 執行安全性檢查,以確保其獲得授權。 判斷目標工作區是否在 ACL 內所花費的時間會隨著工作區數目增加而以指數方式增加。

注意

Power BI 不會透過程式碼強制執行 1,000 個工作區限制。 如果您嘗試,則會將內嵌身分識別新增至超過 1,000 個工作區,而 REST API 呼叫仍會成功執行。 不過,如果您的應用程式會進入不支援的狀態,則在嘗試向 Microsoft 支援服務要求協助時,這可能會造成影響。

假設某個案例中,兩個多租用戶應用程式都已設定為使用單一服務主體。 現在,請考慮第一個應用程式已建立 990 個工作區,而第二個應用程式已建立 1,010 個工作區。 從支援的觀點來看,第一個應用程式位於支援界限內,而第二個應用程式則否。

現在,純粹從效能的觀點來比較這兩個應用程式。 兩者並無太大差異,因為這兩個服務主體的 ACL 都讓其 ACL 的中繼資料成長到會降低效能到某個程度的點。

以下是重點觀察:服務主體所建立的工作區數目對效能和可擴縮性有直接影響。 屬於 100 個工作區成員的服務主體會比屬於 1,000 個工作區成員的服務主體更快地執行 REST API 呼叫。 同樣地,屬於只有 10 個工作區成員的服務主體會比屬於 100 個工作區成員的服務主體更快地執行 REST API 呼叫。

重要

從效能和可擴縮性的觀點來看,服務主體為成員的最佳工作區數目是正好一個

管理語意模型和資料來源認證的隔離

設計多租用戶應用程式的另一個重要層面是隔離客戶租用戶。 一個客戶租用戶的使用者不會看到屬於另一個客戶租用戶的資料,這一點非常重要。 因此,您必須了解如何管理語意模型擁有權和資料來源認證。

語意模型擁有權

每個 Power BI 語意模型都有單一擁有者,可以是使用者帳戶或服務主體。 需要語意模型擁有權,才能設定排程的重新整理和設定語意模型參數。

提示

在 Power BI 服務中,您可以開啟語意模型設定來判斷語意模型擁有者是誰。

如有必要,您可以將語意模型的擁有權轉移給另一個使用者帳戶或服務主體。 您可以在 Power BI 服務中,或使用 REST API TakeOver 作業來執行此操作。 當您匯入 Power BI Desktop 檔案以使用服務主體建立新的語意模型時,服務主體會自動設定為語意模型擁有者。

資料來源認證

若要將語意模型連線到其基礎資料來源,語意模型擁有者必須設定資料來源認證。 資料來源認證會由 Power BI 加密和快取。 此時,Power BI 會在重新整理資料 (適用於匯入儲存體資料表) 或執行傳遞查詢 (適用於 DirectQuery 儲存資料表) 時,使用這些認證向基礎資料來源進行驗證。

建議您在佈建新的客戶租用戶時套用一般設計模式。 您可以使用服務主體的身分識別來執行一系列的 REST API 呼叫:

  1. 建立新工作區。
  2. 建立新工作區與專用容量的關聯。
  3. 匯入 Power BI Desktop 檔案以建立語意模型。
  4. 設定該語意模型的語意模型來源認證。

完成這些 REST API 呼叫時,服務主體將會是新工作區的管理員,以及語意模型和資料來源認證的擁有者。

重要

有一個常見的誤解,語意模型資料來源認證是工作區層級的範圍。 那並非事實。 資料來源認證的範圍是服務主體 (或使用者帳戶),且該範圍會延伸到 Microsoft Entra 租用戶中的所有 Power BI 工作區。

服務主體可以建立資料來源認證,這些認證可由客戶租用戶不同工作區中的語意模型共用,如下圖所示。

圖表顯示兩個租用戶的設定。每個租用戶皆共用相同的資料來源認證。

當資料來源認證由屬於不同客戶租用戶的語意模型共用時,客戶租用戶不會完全隔離。

在服務主體設定檔之前設計策略

了解服務主體設定檔功能可供使用之前的設計策略,可協助您了解此功能的需求。 在此之前,開發人員會使用下列三種設計策略之一來建置多租用戶應用程式:

  • 單一服務主體
  • 服務主體共用
  • 每個工作區一個服務主體

每個設計策略都有相關聯的優缺點。

單一服務主體設計策略需要建立一次 Microsoft Entra 應用程式註冊。 因此,由於不需要建立更多 Microsoft Entra 應用程式註冊,所以其系統管理額外負荷比其他兩個設計策略低。 此策略也是最直接的設定,因為它不需要撰寫額外的程式碼,以在發出 REST API 呼叫時切換服務主體之間的呼叫內容。 不過,此設計策略的問題在於它不會進行調整。 它只支援可成長至 1,000 個工作區的多租用戶環境。 此外,效能一定會降低,因為服務主體已獲授與大量工作區的存取權。 客戶租用戶隔離也存在問題,因為單一服務主體會成為所有客戶租用戶中每個語意模型和所有資料認證的擁有者。

服務主體共用設計策略通常用於避免 1,000 個工作區的限制。 它可讓應用程式藉由將正確的服務主體數目新增至集區,以調整為任意數目的工作區。 例如,五個服務主體的集區可讓您擴大至 5,000 個工作區;80 個服務主體的集區可讓您擴大至 80,000 個工作區等等。 不過,雖然此策略可以調整為大量的工作區,但有數個缺點。 首先,它需要撰寫額外的程式碼並儲存中繼資料,以允許在發出 REST API 呼叫時,在服務主體之間切換內容。 其次,它牽涉到更多的系統管理工作,因為每當您需要增加集區中的服務主體數目時,都必須建立 Microsoft Entra 應用程式註冊。

更重要的是,服務主體共用策略並未針對效能進行最佳化,因為它允許服務主體成為數百個工作區的成員。 從客戶租用戶隔離的觀點來看,這種策略也不理想,因為服務主體可以成為跨客戶租用戶共用的語意模型和資料認證擁有者。

每個工作區一個服務主體設計策略牽涉到為每個客戶租用戶建立服務主體。 從理論上的觀點來看,此策略提供最佳的解決方案,因為它最佳化 REST API 呼叫的效能,同時為工作區層級的語意模型和資料來源認證提供真正的隔離。 然而,理論上最好的策略未必在實務上效果最好。 這是因為對於許多組織而言,為每個客戶租用戶建立服務主體的需求是不切實際的。 這是因為某些組織有正式的核准程序,或涉及建立 Microsoft Entra 應用程式註冊的繁文褥節。 這些原因使得無法授與自訂應用程式所需的授權單位,以視需要建立 Microsoft Entra 應用程式註冊,並以解決方案所需的自動化方式進行。

在自訂應用程式獲得適當權限的較不常見案例中,可以使用 Microsoft Graph API 視需要建立 Microsoft Entra 應用程式註冊。 不過,自訂應用程式通常很複雜而難以進行開發和部署,因為它必須以某種方式追蹤每個 Microsoft Entra 應用程式註冊的驗證認證。 每當需要驗證並取得個別服務主體的存取權杖時,也必須取得這些認證的存取權。

服務主體設定檔

服務主體設定檔功能的設計目的是讓您更輕鬆地管理 Power BI 中的組織內容,並更有效率地使用您的容量。 其可協助解決三個涉及最低開發人員工作和額外負荷的特定挑戰。 這些挑戰包括:

  • 調整為大量的工作區。
  • 最佳化 REST API 呼叫的效能。
  • 在客戶租用戶層級隔離語意模型和資料來源認證。

當您使用服務主體設定檔設計多租用戶應用程式時,可以受益於三種設計策略的優點 (如上一節所述),同時避免其相關聯的弱點。

服務主體設定檔是在 Power BI 內容中建立的本機帳戶。 服務主體可以使用 Profiles REST API 作業來建立新的服務主體設定檔。 服務主體可以針對自訂應用程式建立及管理自己的服務主體設定檔集,如下圖所示。

圖表顯示服務主體在 Power BI 中建立三個服務主體設定檔。

服務主體與所建立的服務主體設定檔之間一律有父子關聯性。 您無法建立服務主體設定檔作為獨立實體。 相反地,您會使用特定的服務主體來建立服務主體設定檔,而該服務主體會作為設定檔的父系。 此外,使用者帳戶或其他服務主體永遠不會看到服務主體設定檔。 服務主體設定檔只能由建立的服務主體查看及使用。

Microsoft Entra 並不會知道服務主體設定檔

雖然 Microsoft Entra 已知服務主體本身及其基礎 Microsoft Entra 應用程式註冊,但 Microsoft Entra ID 並不知道服務主體設定檔的任何內容。 這是因為服務主體設定檔是由 Power BI 所建立,而它們只存在於控制 Power BI 安全性和授權的 Power BI 服務子系統中。

Microsoft Entra ID 不知道服務主體設定檔的現象同時具有優點和缺點。 主要優點是為您的客戶內嵌案例應用程式不需要任何特殊 Microsoft Entra 權限,即可建立服務主體設定檔。 這也表示應用程式可以建立及管理一組與 Microsoft Entra 不同的本機身分識別。

不過,同時也存在缺點。 因為 Microsoft Entra 不知道服務主體設定檔,所以您無法將服務主體設定檔新增至 Microsoft Entra 群組,以隱含地授與工作區的存取權。 此外,外部資料來源如 Azure SQL Database 或 Azure Synapse Analytics,在連線到資料庫時無法將服務主體設定檔辨識為身分識別。 因此,在要求使用個別服務主體搭配每個客戶租用戶的唯一驗證認證來連線到這些資料來源時,每個工作區一個服務主體設計策略 (為每個客戶租用戶建立服務主體) 可能是更好的選擇。

服務主體設定檔是一流的安全性主體

雖然 Microsoft Entra 不知道服務主體設定檔,但 Power BI 會將它們辨識為一流的安全性主體。 如同使用者帳戶或服務主體,您可以將服務主體設定檔新增至工作區角色 (以系統管理員或成員身分)。 您也可以將其設為語意模型擁有者和資料來源認證的擁有者。 基於這些理由,為每個新客戶租用戶建立新的服務主體設定檔是最佳做法。

顯示多個客戶租用戶的圖表,每個租用戶都有自己的服務主體設定檔。

提示

當您使用服務主體設定檔開發為您的客戶內嵌案例應用程式時,只需要建立單一 Microsoft Entra 應用程式註冊,即可為應用程式提供單一服務主體。 相較於其他多租用戶設計策略,此方法可大幅降低系統管理額外負荷,因為必須在應用程式部署至生產環境之後,持續建立額外的 Microsoft Entra 應用程式註冊。

以服務主體設定檔的形式執行 REST API 呼叫

您的應用程式可以使用服務主體設定檔的身分識別來執行 REST API 呼叫。 這表示它可以執行一連串的 REST API 呼叫,以佈建和設定新的客戶租用戶。

  1. 當服務主體設定檔建立新的工作區時,Power BI 會自動將該設定檔新增為工作區管理員。
  2. 當服務主體設定檔匯入 Power BI Desktop 檔案以建立語意模型時,Power BI 會將該設定檔設定為語意模型擁有者。
  3. 當服務主體設定檔設定資料來源認證時,Power BI 會將該設定檔設定為資料來源認證的擁有者。

請務必了解服務主體在 Power BI 中具有與設定檔身分識別不同的獨立身分識別。 這可讓您以開發人員身分進行選擇。 您可以使用服務主體設定檔的身分識別來執行 REST API 呼叫。 或者,您可以使用父服務主體的身分識別,執行不含設定檔的 REST API 呼叫。

建議您在建立、檢視或刪除服務主體設定檔時,以父服務主體身分執行 REST API 呼叫。 您應該使用服務主體設定檔來執行所有其他 REST API 呼叫。 這些其他呼叫可以建立工作區、匯入 Power BI Desktop 檔案、更新語意模型參數,以及設定資料來源認證。 它們也可以擷取工作區項目中繼資料並產生內嵌權杖。

假設您需要為名為 Contoso 的客戶設定客戶租用戶。 第一個步驟會發出 REST API 呼叫來建立服務主體設定檔,並將其顯示名稱設定為 Contoso。 此呼叫是使用服務主體的身分識別來進行。 所有剩餘的設定步驟都會使用服務主體設定檔來完成下列工作:

  1. 建立工作區。
  2. 將工作區與容量建立關聯。
  3. 匯入 Power BI Desktop 檔案。
  4. 設定語意模型參數。
  5. 設定資料來源認證。
  6. 設定排程的資料重新整理。

請務必了解,必須使用用來建立客戶租用戶的服務主體設定檔身分識別,來存取工作區及其內容。 此外,請務必了解父服務主體不需要存取工作區或其內容。

提示

請記住:發出 REST API 呼叫時,請使用服務主體來建立和管理服務主體設定檔,並使用服務主體設定檔來建立、設定及存取 Power BI 內容。

使用設定檔 REST API 作業

設定檔 REST API 作業群組包含建立和管理服務主體設定檔的作業:

  • Create Profile
  • Delete Profile
  • Get Profile
  • Get Profiles
  • Update Profile

建立服務主體設定檔

使用建立設定檔 REST API 作業來建立服務主體設定檔。 您必須在要求本文中設定 displayName 屬性,才能提供新租用戶的顯示名稱。 值在服務主體所擁有的所有設定檔中必須是唯一的。 如果服務主體已有該顯示名稱的另一個設定檔存在,則呼叫將會失敗。

成功的呼叫會傳回 id 屬性,這是代表設定檔的 GUID。 當您開發使用服務主體設定檔的應用程式時,建議您將設定檔顯示名稱及其識別碼值儲存在自訂資料庫中。 如此一來,您的應用程式就能直接擷取識別碼。

如果您是使用 Power BI .NET SDK 進行程式設計,則可以使用 Profiles.CreateProfile 方法,這個方法會傳回代表新設定檔的 ServicePrincipalProfile 物件。 它可讓您直接判斷 id 屬性值。

以下是建立服務主體設定檔並將授與其工作區存取權的範例。

// Create a service principal profile
string profileName = "Contoso";

var createRequest = new CreateOrUpdateProfileRequest(profileName);
var profile = pbiClient.Profiles.CreateProfile(createRequest);

// Retrieve the ID of the new profile
Guid profileId = profile.Id;

// Grant workspace access
var groupUser = new GroupUser {
    GroupUserAccessRight = "Admin",
    PrincipalType = "App",
    Identifier = ServicePrincipalId,
    Profile = new ServicePrincipalProfile {
        Id = profileId
    }
};

pbiClient.Groups.AddGroupUser(workspaceId, groupUser);

在 Power BI 服務中,在工作區 [存取] 窗格中,您可以決定哪些身分識別 (包括安全性主體) 具有存取權。

顯示工作區 [存取] 窗格螢幕擷取畫面的螢幕擷取畫面。它會顯示具有系統管理員權限之 Contoso 顯示名稱的服務主體設定檔。

刪除服務主體設定檔

使用刪除設定檔 REST API 作業來刪除服務主體設定檔。 此作業只能由父服務主體呼叫。

如果您是使用 Power BI .NET SDK 進行程序設計,則可以使用 Profiles.DeleteProfile 方法。

擷取所有服務主體設定檔

使用取得設定檔 REST API 作業來擷取屬於呼叫服務主體的服務主體設定檔清單。 此作業會傳回 JSON 承載,其中包含每個服務主體設定檔的 iddisplayName 屬性。

如果您是使用 Power BI .NET SDK 進行程序設計,則可以使用 Profiles.GetProfiles 方法。

使用服務主體設定檔執行 REST API 呼叫

使用服務主體設定檔發出 REST API 呼叫有兩個需求:

  • 您必須在授權標頭中傳遞父服務主體的存取權杖。
  • 您必須包含名為 X-PowerBI-profile-id 的標頭,其中包含服務主體設定檔識別碼的值。

如果您使用 Power BI .NET SDK,則可以傳遞服務主體設定檔的識別碼,以明確地設定 X-PowerBI-profile-id 標頭值。

// Create the Power BI client
var tokenCredentials = new TokenCredentials(GetACcessToken(). "Bearer");
var uriPowerBiServiceApiRoot = new Uri(uriPowerBiServiceApiRoot);
var pbiClient = new PowerBIClient(uriPowerBiServiceApiRoot, tokenCredentials);

// Add X-PowerBI-profile-id header for service principal profile
string profileId = "11111111-1111-1111-1111-111111111111";
pbiClient.HttpClient.DefaultRequestHeaders.Add("X-PowerBI-profile-id", profileId);

// Retrieve workspaces by using the identity of service principal profile
var workspaces = pbiClient.Groups.GetGroups();

如上述範例所示,一旦您將 X-PowerBI-profile-id 標頭新增至 PowerBIClient 物件,即可直接叫用方法,例如 Groups.GetGroups,因此會使用服務主體設定檔來執行它們。

PowerBIClient 物件設定 X-PowerBI-profile-id 標頭有更方便的方式。 您可以將設定檔的識別碼傳遞至建構函式,以初始化物件。

// Create the Power BI client
string profileId = "11111111-1111-1111-1111-111111111111";

var tokenCredentials = new TokenCredentials(GetACcessToken(). "Bearer");
var uriPowerBiServiceApiRoot = new Uri(uriPowerBiServiceApiRoot);
var pbiClient = new PowerBiClient(uriPowerBiServiceApiRoot, tokenCredentials, profileId);

當您對多租用戶應用程式進行程式設計時,可能需要在以父服務主體身分執行呼叫和以服務主體設定檔的形式執行呼叫之間切換。 管理內容切換的實用方法是宣告儲存 PowerBIClient 物件的類別層級變數。 然後,您可以建立協助程式方法,以正確的物件設定變數。

// Class-level variable that stores the PowerBIClient object
private PowerBIClient pbiClient;

// Helper method that sets the correct PowerBIClient object
private void SetCallingContext(string profileId = "") {

    if (profileId.Equals("")) {
        pbiClient = GetPowerBIClient();    
    }
    else {
        pbiClient = GetPowerBIClientForProfile(new Guid(profileId));
    }
}

當您需要建立或管理服務主體設定檔時,可以呼叫 SetCallingContext 方法,而不需要任何參數。 如此一來,您可以使用服務主體的身分識別來建立和管理設定檔。

// Always create and manage profiles as the service principal
SetCallingContext();

// Create a service principal profile
string profileName = "Contoso";

var createRequest = new CreateOrUpdateProfileRequest(profileName);
var profile = pbiClient.Profiles.CreateProfile(createRequest);

當您需要為新的客戶租用戶建立和設定工作區時,您想要以服務主體設定檔的形式執行該程式碼。 因此,您應該藉由傳入設定檔的識別碼來呼叫 SetCallingContext 方法。 如此一來,您可以使用服務主體設定檔的身分識別來建立工作區。

// Always create and set up workspaces as a service principal profile
string profileId = "11111111-1111-1111-1111-111111111111";
SetCallingContext(profileId);

// Create a workspace
GroupCreationRequest request = new GroupCreationRequest(workspaceName);
Group workspace = pbiClient.Groups.CreateGroup(request);

當您使用特定的服務主體設定檔來建立和設定工作區之後,您應該繼續使用相同的設定檔來建立和設定工作區內容。 不需要叫用 SetCallingContext 方法即可完成設定。

開發人員範例

建議您下載名為 AppOwnsDataMultiTenant 的範例應用程式。

此範例應用程式是使用 .NET 6 和 ASP.NET 所開發,並示範如何套用本文中所述的指導和建議。 您可以檢閱程式碼,了解如何使用服務主體設定檔來開發多租用戶應用程式,以實作為您的客戶內嵌案例。

如需本文的詳細資訊,請參閱下列資源︰