嵌套应用身份验证

注意

  • 嵌套应用身份验证 (NAA) 仅在 公共开发人员预览版中可用。
  • NAA 仅在单页应用程序 (SPA) (如选项卡)中受支持。

NAA 是嵌入主机环境(如 Teams、Outlook 和 Microsoft 365)中的 SPA 的新身份验证协议。 它简化了身份验证过程,以便跨嵌套在受支持的主机应用中的应用 (SSO) 单一登录。 NAA 模型支持主机应用的主要标识,其中包含嵌套应用的多个应用标识。 Microsoft在 Teams 选项卡、个人应用和 Office 加载项中使用此模型。

NAA 模型比代表 (OBO) 流具有多个优势:

  • NAA 要求你仅使用 MSAL.js 库。 无需在 TeamsJS) (Teams JavaScript 客户端库中使用 getAuthToken 函数。
  • 可以使用来自客户端代码的访问令牌(作为 SPA)调用 Microsoft Graph 等服务。 无需使用中间层服务器。
  • 可以对范围使用增量和动态许可 (权限) 。
  • 无需预授权主机(例如 Teams 或 Microsoft 365)来调用终结点。

下表概述了 Teams Microsoft Entra SSO 与 NAA 之间的差异:

开发所需的步骤 传统 Teams Entra SSO NAA
公开重定向 URI 必需 必需
在 Microsoft Entra ID 中注册 API 必需
在 Microsoft Entra ID 中定义自定义范围 必需
授权 Teams 客户端应用 必需
修改应用清单 (以前称为 Teams 应用清单) 必需 推荐*
通过 TeamsJS SDK 获取访问令牌 必需
请求用户同意以获得更多权限 必需
在服务器上执行 OBO 交换 必需
  • IT 管理员可能会在 Microsoft Entra ID 中阻止应用或仅同意应用的特定权限。 若要避免这种情况,必须在应用清单中包含应用 ID 和默认资源,以便管理员在 Teams 管理中心批准权限。

NAA 的用例

应用场景 说明
同意 SSO (和其他权限) Tom 是 Contoso 设计团队的新成员,需要使用 Teams 会议中的 Contoso 应用来协作处理白板。 首次使用时,对话框会提示 Tom 授予权限,包括读取其头像 (User.Read) 的个人资料。 同意后,Tom 可以在将来的跨设备会议中无缝使用 Contoso。
重新身份验证或条件访问升级身份验证 Tom 在澳大利亚工作时遇到条件访问触发器,需要多重身份验证 (MFA) 才能访问 Teams 中的 Contoso。 一个对话框通知 Tom 需要进行更多验证,引导他们完成 MFA 过程以继续使用 Contoso。
错误 由于检索帐户信息时出现问题,Tom 面临 Contoso 登录错误。 Tom 遇到提示重新进行身份验证的重试按钮。 但是,他们发现系统管理员已限制对 Contoso 的访问权限。

配置 NAA

注意

  • 由于 NAA 处于开发人员预览阶段且不受所有主机环境支持,因此请确保使用 isNAAChannelRecommended () 函数检查支持状态,并为不受支持的环境提供回退体验。
  • 如果 API 将值返回为 true,则调用 Microsoft 身份验证库 (NAA 流的 MSAL) 。 如果返回 false,请继续使用现有的令牌检索方法。

若要配置嵌套身份验证,请执行以下步骤:

  1. 注册 SPA
  2. 添加受信任的代理
  3. 初始化公共客户端应用
  4. 获取第一个令牌
  5. 调用 API

注册 SPA

必须在 Azure 门户 上为加载项创建Microsoft Entra ID应用注册。 应用注册必须具有名称、支持的帐户类型和 SPA 重定向。 注册应用后,Azure 门户会生成Microsoft Entra应用注册 ID。 如果外接程序需要除 NAA 和 SSO 以外的其他应用注册,请参阅 注册单页应用程序

添加受信任的代理

若要配置嵌套应用身份验证,应用必须主动配置应用的重定向 URI。 重定向 URI 向Microsoft 标识平台指示支持主机可以中转应用。 应用的重定向 URI 必须是 单页应用程序 类型,并且符合以下方案:

brk-multihub://<your_domain>

其中:

  • brk-multihub 使身份验证可由配置为运行的任何Microsoft 365 支持的主机(例如 Teams、Outlook 或 Microsoft365.com)中转。
  • < > your_domain是托管应用的完全限定域名。 例如 ,brk-multihub://contoso.com

域必须仅包含源,而不能包含其子路径。 例如:

✔️ brk-multihub://myapp.teams.microsoft.com
❌ brk-multihub://myapp.teams.microsoft.com/go

有关将 Teams 应用升级为在 Outlook 和 Microsoft365.com 中运行的详细信息,请参阅 跨 Microsoft 365 扩展 Teams 应用

初始化公共客户端应用

注意

若要确保身份验证成功,请在初始化 MSAL 之前初始化 TeamsJS。

根据需要初始化 MSAL 并获取公共客户端应用的实例以获取访问令牌。

import {
  AccountInfo,
  IPublicClientApplication,
  createNestablePublicClientApplication,
} from "@azure/msal-browser";

const msalConfig = {
  auth: {
    clientId: "your_client_id",
    authority: "https://login.microsoftonline.com/{your_tenant_id}",
    supportsNestedAppAuth: true
  },
};

let pca: IPublicClientApplication;

export function initializePublicClient() {
  console.log("Starting initializePublicClient");
  return createNestablePublicClientApplication(msalConfig).then(
    (result) => {
      console.log("Client app created");
      pca = result;
      return pca;
    }
  );
}

获取第一个令牌

MSAL.js 通过嵌套应用身份验证获取的令牌将为Microsoft Entra应用注册 ID 颁发。 MSAL.js 处理用户身份验证的令牌获取。 它尝试以无提示方式获取访问令牌。 如果这不成功,它会提示用户同意。 然后,该令牌用于调用Microsoft 图形 API或其他Microsoft Entra ID受保护的资源。 与 OBO 流不同,无需预授权主机来调用终结点。

若要获取令牌,请执行以下步骤:

  1. 使用 MSAL.js 获取应用 ID 的令牌。 有关详细信息,请参阅 获取和使用访问令牌

  2. 使用 getActiveAccount API 验证是否有活动帐户来调用 publicClientApplication。 如果没有活动帐户,请尝试使用 其他筛选器参数(如 tenantIDhomeAccountIdloginHint)从上下文接口检索缓存getAccount中的帐户。

    注意

    属性 homeAccountId 等效于 userObjectId TeamsJS 中。

  3. 调用 publicClientApplication.acquireTokenSilent(accessTokenRequest) 以无提示方式获取令牌,无需用户交互。 accessTokenRequest 指定请求访问令牌的范围。 NAA 支持增量和动态同意。 确保始终请求代码完成其任务所需的最小范围。

  4. 如果没有可用的帐户,MSAL.js 将 InteractionRequiredAuthError返回 。 调用 publicClientApplication.acquireTokenPopup(accessTokenRequest) 以显示用户的交互式对话。 acquireTokenSilent 如果令牌过期或用户未同意所有请求的范围,则可能会失败。

以下代码片段显示了访问令牌的示例:


  // MSAL.js exposes several account APIs, logic to determine which account to use is the responsibility of the developer
  const account = publicClientApplication.getActiveAccount();

  const accessTokenRequest = {
  scopes: ["user.read"],
  account: account,
  };

  publicClientApplication
    .acquireTokenSilent(accessTokenRequest)
    .then(function (accessTokenResponse) {
      // Acquire token silent success
      let accessToken = accessTokenResponse.accessToken;
      // Call your API with token
      callApi(accessToken);
    })
    .catch(function (error) {
      //Acquire token silent failure, and send an interactive request
      if (error instanceof InteractionRequiredAuthError) {
        publicClientApplication
          .acquireTokenPopup(accessTokenRequest)
          .then(function (accessTokenResponse) {
            // Acquire token interactive success
            let accessToken = accessTokenResponse.accessToken;
            // Call your API with token
            callApi(accessToken);
          })
          .catch(function (error) {
            // Acquire token interactive failure
            console.log(error);
          });
      }
      console.log(error);
    });

调用 API

收到令牌后,使用它调用 API。 这可确保使用有效的令牌调用 API,以向服务器发出经过身份验证的请求。

以下示例演示如何向Microsoft 图形 API发出经过身份验证的请求,以访问Microsoft 365 数据:


var headers = new Headers();
var bearer = "Bearer " + access_token;
headers.append("Authorization", bearer);
var options = {
    method: "GET",
    headers: headers
};

var graphEndpoint = "<https://graph.microsoft.com/v1.0/me>";

fetch(graphEndpoint, options)
    .then(function (response) {
        //do something with response
    });

最佳做法

  • 尽可能使用无提示身份验证:MSAL.js 提供了 acquireTokenSilent 方法,该方法通过在不提示用户的情况下发出无提示令牌请求来处理令牌续订。 方法首先在浏览器存储中查找有效的缓存令牌。 如果找不到,库会向Microsoft Entra ID发出无提示请求,如果存在活动用户会话 (由Microsoft Entra域) 上的浏览器中设置的 Cookie 确定,Microsoft Entra ID将返回新的令牌。 库不会自动调用 acquireTokenSilent 方法。 建议在进行 API 调用 acquireTokenSilent 之前在应用中调用 以获取有效令牌。

    在某些情况下,尝试使用 方法获取令牌失败 acquireTokenSilent 。 例如,当应用用户Microsoft Entra ID过期的用户会话或密码更改时,acquireTokenSilent会失败。 () acquireTokenPopup 调用交互式获取令牌方法。

  • 具有回退:NAA 流提供跨Microsoft生态系统的兼容性。 但是,你的应用可能显示在未更新为支持 NAA 的下层客户端或旧版客户端中。 在这种情况下,你的应用不能支持无缝 SSO,你可能需要调用特殊的 API 来与用户交互以打开身份验证对话框。 有关详细信息,请参阅 为选项卡应用启用 SSO

    注意

    如果使用非Microsoft Entra标识提供者,则不得使用 NAA,可以改用弹出身份验证。

  • 对 NAA 的支持:并非所有主机应用环境都支持 NAA。 若要验证当前客户端是否支持此功能,可以调用指定的 API 来确定其状态。 返回值 表示 true 对 NAA 的支持,但 false 表示不支持 NAA。

  • 在多个环境中测试应用:如果你的应用预期同时在 Web 视图和浏览器部署中运行,我们建议在这两个部署环境中测试你的应用,以确保其按预期运行。 浏览器中运行的某些 API 可能无法在 Web 视图中运行。

代码示例

示例名称 Description .NET Node.js
嵌套应用身份验证 此示例演示如何为主机环境(如 Teams、Outlook 和 Microsoft 365)中嵌入的 SPA 生成 NAA 协议。 View View

另请参阅