Microsoft Fabric 中的工作负荷身份验证指南概述
本文提供了有关如何在构建 Microsoft Fabric 工作负载时使用身份验证的指南。 它包括有关使用令牌和同意的信息。
在开始之前,请确保熟悉 身份验证概述 和 身份验证设置中的概念。
数据平面和控制平面 API
数据平面 API 是工作负荷后端公开的 API。 工作负荷前端可以直接调用它们。 对于数据平面 API,工作负载后端可以决定要公开哪些 API。
控制平面 API 是通过 Fabric 传递的 API。 此过程从工作负载前端调用 JavaScript API 开始,以 Fabric 调用工作负载后端结束。 此类 API 的示例为“创建项”。
对于控制平面 API,工作负荷必须遵循工作负荷后端中定义的协定并实现这些 API。
在 Microsoft Entra ID 中公开工作负荷应用程序的 API 选项卡
在 “公开 API”选项卡上,需要添加控制平面 API 的权限范围和数据平面 API 的权限范围:
为控制平面 API 添加的范围应使用应用程序 ID
d2450708-699c-41e3-8077-b0c8341509aa
预授权适用于工作负荷应用程序的 Fabric 客户端。 当 Fabric 调用时,这些作用域包括在其发送到工作负荷后端的令牌中。需要为控制平面 API 至少添加一个范围才能使流正常工作。
为数据平面 API 添加的范围应使用应用程序 ID
871c010f-5e61-4fb1-83ac-98610a7e9110
预授权Microsoft Power BI。 这些内容包含在acquireAccessToken
JavaScript API 返回的令牌中。对于数据平面 API,您能够使用此选项卡管理工作负荷公开的每个 API 的详细权限。 理想情况下,应为工作负荷后端公开的每个 API 添加一组范围,并在从客户端调用这些 API 时验证收到的令牌是否包括这些作用域。 例如:
- 工作负荷向客户端公开两个 API,
ReadData
和WriteData
。 - 工作负荷暴露了两个数据平面范围,
data.read
和data.write
。 - 在
ReadData
API 中,任务在继续流程之前验证令牌中是否包含data.read
范围。 这同样适用于WriteData
。
- 工作负荷向客户端公开两个 API,
Microsoft Entra ID 中工作负荷的应用程序上的“API 权限”选项卡
在 API 权限 选项卡上,您需要添加您的工作负荷需要使用令牌交换的所有权限范围。 要添加的必需范围是在 Power BI 服务下 Fabric.Extend
。 对 Fabric 的请求可能会在没有这个范围的情况下失败。
使用令牌和同意
使用数据平面 API 时,工作负荷前端需要获取令牌来调用工作负荷后端。
以下部分介绍了工作负荷前端如何使用 JavaScript API 和 代表 (OBO) 流 获取工作负载和外部服务的令牌,以及处理同意。
步骤 1:获取令牌
工作负载首先使用 JavaScript API 请求令牌,而无需提供任何参数。 此调用可能会导致两种情况:
用户看到工作负载配置的所有静态依赖项(API 权限 选项卡上配置的内容)的同意窗口。 如果用户不是应用程序所属的主租户的一部分,并且以前没有为此应用程序授予对Microsoft Graph的访问权限,则会出现这种情况。
用户看不到同意窗口。 这种情况会发生在用户已经至少同意过一次此应用程序使用Microsoft Graph,或者用户是该应用程序的主租户成员。
在这两种情况下,工作负荷都不应关心用户是否对所有依赖项(此时无法知道)给予完全同意。 收到的令牌涵盖工作负载后端受众,可用于直接从工作负载前端调用工作负载后端。
步骤 2:尝试访问外部服务
工作负荷可能需要访问需要身份验证的服务。 对于该访问,它需要执行 OBO 流,在该流中,它将从客户端或 Fabric 接收的令牌交换到另一个服务。 由于缺少同意或某些Microsoft在工作负荷尝试交换令牌的资源上配置的 Entra 条件访问策略,令牌交换可能会失败。
若要解决此问题,工作负载负责在前端和后端之间直接调用时将错误传播到客户端。 使用 工作负荷通信中所述的错误传播,在处理来自 Fabric 的调用时,工作负荷也有责任将错误传播到客户端。
工作负荷传播错误后,可以调用 acquireAccessToken
JavaScript API 来解决同意或条件访问策略问题,然后重试操作。
有关数据平面 API 失败,请参阅 处理多重身份验证、条件访问和增量同意。 有关控制平面 API 故障,请参阅 工作负荷通信。
示例方案
让我们看看需要访问三个 Fabric API 的工作负荷:
列出工作区:
GET https://api.fabric.microsoft.com/v1/workspaces
创建仓库:
POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/warehouses
将数据写入 lakehouse 文件:
PUT https://onelake.dfs.fabric.microsoft.com/{filePath}?resource=file
若要能够使用这些 API,工作负载后端需要交换以下范围的令牌:
- 要列出工作区:
https://analysis.windows.net/powerbi/api/Workspace.Read.All
或https://analysis.windows.net/powerbi/api/Workspace.ReadWrite.All
- 创建仓库:
https://analysis.windows.net/powerbi/api/Warehouse.ReadWrite.All
或https://analysis.windows.net/powerbi/api/Item.ReadWrite.All
- 若要写入 Lakehouse 文件:
https://storage.azure.com/user_impersonation
前面提到的范围需要在 API 权限下的工作负荷应用程序上配置。
让我们看看负载可能遇到的情景示例。
示例 1
假设工作负荷后端有一个数据平面 API,用于获取用户的工作区并将其返回到客户端:
工作负载前端使用 JavaScript API 请求令牌。
工作负载前端调用工作负载后端 API 以获取用户的工作区,并在请求中附加令牌。
工作负载后端会验证令牌,并尝试将其交换为所需的范围(假设
https://analysis.windows.net/powerbi/api/Workspace.Read.All
)。工作负荷无法交换指定资源的令牌,因为用户未同意应用程序访问此资源(请参阅 AADSTS 错误代码)。
工作后端系统通过指定需要得到对该资源的同意,将错误传递到工作前端系统。 负载前端调用
acquireAccessToken
JavaScript API 并提供additionalScopesToConsent
:workloadClient.auth.acquireAccessToken({additionalScopesToConsent: ["https://analysis.windows.net/powerbi/api/Workspace.Read.All"]})
或者,工作负载可以决定请求同意其应用程序上配置的所有静态依赖项,因此调用 JavaScript API 并提供
promptFullConsent
。workloadClient.auth.acquireAccessToken({promptFullConsent: true})
。
无论用户是否同意某些依赖项,此调用都会提示同意窗口。 之后,工作负荷前端可以重试该操作。
注意
如果令牌交换在同意错误时仍然失败,则表示用户未授予许可。 工作任务需要处理此类情况,例如,通知用户此 API 需要同意,否则将无法使用。
示例 2
假设工作负荷后端需要通过创建项 API 访问 OneLake(从 Fabric 调用到工作负荷):
工作负荷前端调用“创建项目”JavaScript API。
工作负载后台接收到来自 Fabric 的调用后,提取委托令牌,并对其进行验证。
工作负荷尝试为
https://storage.azure.com/user_impersonation
交换令牌,但由于 Azure 存储访问所需的用户配置多重身份验证的租户管理员设置不当而失败(请参阅 AADSTS 错误代码)。工作负荷根据 工作负荷通信中的错误传播描述,将 Microsoft Entra ID 返回的错误和相关声明一起传递给客户端。
工作负荷前端调用
acquireAccessToken
JavaScript API,并提供声明作为claimsForConditionalAccessPolicy
,其中claims
引用从工作负荷后端传播的声明:workloadClient.auth.acquireAccessToken({claimsForConditionalAccessPolicy: claims})
之后,工作负荷可以重试该操作。
请求同意时处理错误
有时,由于各种错误,用户无法授予许可。 同意请求后,响应将返回到重定向 URI。 在我们的示例中,此代码负责处理响应。 (可以在index.ts文件中找到它。
const redirectUriPath = '/close';
const url = new URL(window.location.href);
if (url.pathname?.startsWith(redirectUriPath)) {
// Handle errors, Please refer to https://zcusa.951200.xyz/entra/identity-platform/reference-error-codes
if (url?.hash?.includes("error")) {
// Handle missing service principal error
if (url.hash.includes("AADSTS650052")) {
printFormattedAADErrorMessage(url?.hash);
// handle user declined the consent error
} else if (url.hash.includes("AADSTS65004")) {
printFormattedAADErrorMessage(url?.hash);
}
}
// Always close the window
window.close();
}
工作负荷前端可以从 URL 中提取错误代码,并相应地对其进行处理。
注意
在这两种情况下(错误和成功),工作任务必须始终立即关闭窗口,且不会延迟。