在 SharePoint 框架解决方案中连接到受 Azure AD 保护的 API

生成 SharePoint 框架解决方案时,可能需要连接到受 Azure Active Directory (Azure AD) 保护的 API。 借助 SharePoint 框架,可以指定解决方案需要的 Azure AD 应用程序和权限,而且全局或 SharePoint 管理员也能授予必要的权限(如果尚未授予的话)。 使用 AadHttpClient,可以轻松连接到受 Azure AD 保护的 API,而无需自行实现 OAuth 流。

Web API 权限概述

Azure AD 保护许多资源,从 Office 365 到组织生成的自定义业务线应用程序,无所不包。 应用程序必须获取有效的访问令牌,以拥有对特定资源的访问权限,才能连接到这些资源。 应用程序可以在 OAuth 授权流期间获取访问令牌。

对于无法存储机密的客户端应用程序(如 SharePoint 框架解决方案),使用特定类型的 OAuth 流,即 OAuth 隐式流

生成客户端解决方案的开发人员负责使用 OAuth 隐式流在应用程序中实现授权。 在 SharePoint 框架解決方案中,这已通过 SharePoint 框架 v1.4.1 中引入的 MSGraphClientAadHttpClient 在框架中完成。

注意

如果在版本低于 v1.4.1 的 SharePoint 框架中生成解决方案,仍可以连接到受 Azure AD 保护的资源。 在这种情况下,需要直接使用 Microsoft 标识平台身份验证库来实现 OAuth 隐式流。 有关详细信息,请参阅连接到受 Azure Active Directory 保护的 API

SharePoint 框架中有一个特定流程,定义了开发人员如何请求权限,以及管理员如何管理对受 Azure AD 保护的资源的权限。 下面的架构展示了此流程。

架构:展示了请求获取、授予和使用对 Azure AD 应用程序的权限的流程

如果要生成的 SharePoint 框架解决方案需要访问受 Azure AD 保护的特定资源,开发人员要在解决方案清单中列出这些资源,以及所需的权限范围。 在开发人员将解决方案包部署到应用程序目录时,SharePoint 会创建权限请求,并提示管理员管理请求获取的权限。 对于每个请求获取的权限,全局或 SharePoint 管理员都可以决定是要授予还是拒绝授予此权限。

所有权限都是授予给整个租户,而不是请求获取权限的具体应用程序。 如果管理员授予特定权限,它就会被添加到 “SharePoint Online 客户端扩展性” Azure AD 应用程序。Microsoft 在每个 Azure AD 中预配此应用程序,以供 SharePoint 框架在 OAuth 流中为解决方案提供有效的访问令牌。

发现可连接到的应用程序和权限

可以在解决方案中请求获取其权限的应用程序,取决于保护 Office 365 租户的目标 Azure Active Directory。 可连接到的应用程序列表具体可能取决于组织要使用的 Office 365 许可证,以及在 Azure AD 中注册的业务线应用程序。 如果拥有足够权限,可以通过多种方式确定在租户中可连接到的应用程序和权限范围。

使用 Azure 门户或 Azure AD 管理中心

若要查看可连接到的 Azure AD 应用程序列表,一种方法是转到 Azure 门户,或转到 Azure AD 管理中心

  1. 在 Azure AD 管理中心的左侧导航栏中,选择“企业应用程序”链接。

    Azure AD 门户中突出显示的“企业应用程序”链接

  2. 在“企业应用程序”边栏选项卡上,单击“管理”组中的“所有应用程序”链接。

    Azure AD 门户中突出显示的“所有应用程序”链接

  3. 若要快速找到要连接到的应用程序,可以按应用程序类型(“Microsoft 应用程序”或“企业应用程序”)筛选“概述”,也可以按名称或 ID 搜索应用程序。

    例如,若要请求获取对 Microsoft Graph 的其他权限,请在搜索框中搜索“graph”。

    在 Azure AD 门户中的可连接到 Azure AD 应用程序列表中搜索“graph”

  4. 找到应用程序后,选择它即可了解其他信息。 转到应用程序边栏选项卡后,选择“管理”组中的“属性”,打开应用程序属性。

    在 Azure AD 门户的应用程序边栏选项卡上突出显示的“属性”链接

  5. 复制属性列表中的“对象 ID”属性值,在请求获取对 Microsoft Graph 的其他权限范围时需要用到它。 也可以复制应用程序的“名称”属性值,并在权限请求中改用它。

    从 Azure AD 门户中复制到剪贴板的“对象 ID”属性值

注意

虽然“对象 ID”属性值对每个租户是唯一的,但应用程序的“名称”属性值在所有租户中都是相同的。 若要生成解决方案一次,并将它部署到不同的租户中,应在解决方案中使用应用程序的“名称”属性值,请求获取其他权限。

使用 Azure PowerShell

注意

必须先安装 Azure PowerShell,然后才能执行以下步骤。 也可以在 Azure Cloud Shell PowerShell 中执行此部分提及的 cmdlet。

  1. 在 PowerShell 中运行下面的代码,以登录 Azure 订阅(如果使用的是 Azure Cloud Shell,无需这样做):

    Login-AzureRmAccount
    
  2. 输入以下代码,列出在租户中可连接到的应用程序:

    Get-AzureRmADServicePrincipal | sort DisplayName | ft DisplayName, Id
    

    运行此 cmdlet 可列出在租户中可连接到的所有应用程序。 对于每个应用程序,它的显示名称和对象 ID 都会显示,可以在 SharePoint 框架解决方案中用它们来请求获取应用程序权限。

使用 Azure CLI

注意

必须先安装 Azure CLI,然后才能执行以下步骤。 也可以通过 Azure Cloud Shell 或以 Docker 容器形式运行 Azure CLI。

  1. 若要在计算机或 Docker 容器中运行 CLI,请先运行下面的代码,以连接到 Azure 订阅:

    azure login
    
  2. 建立连接后,执行以下命令,列出所有可连接到的 Azure AD 应用程序:

    azure ad sp list --query "sort_by([*].{displayName: displayName, objectId: objectId}, &displayName)" -o table
    

    运行此命令会列出所有可以在租户中连接到的 Azure AD 应用程序(按 displayName 排序)。 对于每个应用程序,此命令都会显示它的 displayName 和 objectId。 此外,输出还会格式化为表。

获取应用程序公开的权限范围列表

每个 Azure AD 应用程序都会公开许多权限范围。 这些权限范围通常与应用程序内的特定资源或操作相关。 若要获取对要连接到的应用程序的权限列表,请参阅它的文档。 有关 Microsoft Graph 支持的权限范围列表,请参阅 Microsoft Graph 权限参考

请求获取对 Azure AD 应用程序的权限

如果 SharePoint 框架解决方案需要获取对受 Azure AD 保护的特定资源(如 Microsoft Graph 或企业应用程序)的权限,可以在解决方案配置中指定这些资源以及必需权限。

  1. 在 SharePoint 框架项目中,打开“config/package-solution.json”文件。

  2. solution属性中添加webApiPermissionRequests属性,用于列出解决方案所需的全部资源和相应权限。

    下面的示例 SharePoint 框架解决方案请求获取访问权限,以使用 Microsoft Graph 读取用户日历:

    {
      "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
      "solution": {
        "name": "spfx-graph-client-side-solution",
        "id": "5d16587c-5e87-44d7-b658-1148988f212a",
        "version": "1.0.0.0",
        "includeClientSideAssets": true,
        "skipFeatureDeployment": true,
        "webApiPermissionRequests": [
          {
            "resource": "Microsoft Graph",
            "scope": "Calendars.Read"
          }
        ]
      },
      "paths": {
        "zippedPackage": "solution/spfx-graph.sppkg"
      }
    }
    

    注意

    若要获取 resource 的属性值,需要指定想要请求获取其权限的应用程序的 displayName。 如果使用 objectId 指定资源,则在尝试批准权限请求时会出现错误。

  3. 若要请求获取对给定资源的多个权限范围,请在单独条目中指定各个范围,例如:

    {
      "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
      "solution": {
        "name": "spfx-graph-client-side-solution",
        "id": "5d16587c-5e87-44d7-b658-1148988f212a",
        "version": "1.0.0.0",
        "includeClientSideAssets": true,
        "skipFeatureDeployment": true,
        "webApiPermissionRequests": [
          {
            "resource": "Microsoft Graph",
            "scope": "Calendars.Read"
          },
          {
            "resource": "Microsoft Graph",
            "scope": "User.ReadBasic.All"
          }
        ]
      },
      "paths": {
        "zippedPackage": "solution/spfx-graph.sppkg"
      }
    }
    
  4. 在此解决方案部署到 SharePoint 应用程序目录后,它会提示管理员验证请求获取的权限,并授予或拒绝授予权限。

    注意

    无论管理员是拒绝还是批准授予请求获取的权限,解决方案都可以在网站上部署和使用。 生成需要其他权限的解决方案时,不得假定请求获取的权限已授予。

管理权限请求

在请求获取对 Azure AD 应用程序的权限的 SharePoint 框架解决方案部署后,系统就会提示管理员管理随解决方案一起提供的权限请求。 可以多种方式管理权限请求。

管理新 SharePoint 管理中心里的权限

若要了解如何使用新 SharePoint 管理中心里的 API 访问页面,请参阅 管理被 Azure AD 保护的 API 访问

使用 PowerShell 管理权限

全局或 SharePoint 管理员可以使用 SharePoint Online 命令行管理程序,在 SharePoint Online 中管理权限和权限请求。

  • 若要查看所有待定权限请求,请运行 Get-SPOTenantServicePrincipalPermissionRequests cmdlet。 对于每个权限请求,此 cmdlet 都会列出它的 ID(批准或拒绝请求所必需)、请求获取其权限的资源,以及请求获取的权限。

    注意

    SharePoint 不会验证请求获取的权限是否已授予。因此,在批准或拒绝权限请求前,请务必先检查已在租户中授予的权限。

  • 若要 批准特定权限请求,请使用 Approve-SPOTenantServicePrincipalPermissionRequest -RequestId <Guid> cmdlet,指定要批准的权限请求的 ID。

    注意

    如果试图批准已授予的权限请求,将会看到错误消息。

  • 若要 拒绝 ( 已授予请求的权限,或者请求违反组织策略) ,请使用 Deny-SPOTenantServicePrincipalPermissionRequest -RequestId <Guid cmdlet> ,指定要拒绝的权限请求的 ID。

    注意

    如果 SharePoint 框架应用程序发出的权限请求遭拒,并不会阻止应用程序部署到应用程序目录中和安装到网站中。

  • 若要查看已在租户中授予的权限,请运行 Get-SPOTenantServicePrincipalPermissionGrants cmdlet。 对于每个已授予权限,此 cmdlet 都会显示以下信息:

    • ClientId:授权许可通过模拟用户来访问资源(由 resourceId 表示)的服务主体的 objectId。
    • ConsentType:许可是由管理员代表组织授予,还是由个人授予。 可取值为“AllPrincipals”或“Principal”。
    • ObjectId:已授予权限的唯一标识符。
    • Resource:已授予对其访问权限的资源。
    • ResourceId:已授予对其访问权限的资源服务主体的 objectId。
    • Scope:资源应用程序应在 OAuth 2.0 访问令牌中获取的范围声明值。
  • 若要 撤销以前授予的权限,请使用 Revoke-SPOTenantServicePrincipalPermission -ObjectId <String> cmdlet。 在 ObjectId 参数中,应指定要撤销的已授予权限的 objectId,可通过运行 Get-SPOTenantServicePrincipalPermissionGrants cmdlet 获取它。

    注意

    撤销权限不会触发对应用程序目录或所有已部署应用程序的任何更改。 撤销权限的唯一后果是,租户中的任何应用程序将无法连接到已撤销对其权限的资源。

使用适用于 Microsoft 365 的 CLI 管理权限

全局或 SharePoint 管理员可以使用适用于 Microsoft 365 的 CLI 在 SharePoint Online 中管理权限和权限请求。

注意

CLI for Microsoft 365是一种开放源代码解决方案,其中包含为其提供支持的活动社区。 没有用于 Microsoft 开放源代码工具支持的 SLA。

  • 若要查看所有待定权限请求,请运行 spo serviceprincipal permissionrequest list 命令。 对于每个权限请求,此命令都会列出它的 ID(批准或拒绝请求所必需)、请求获取其权限的资源,以及请求获取的权限。

    注意

    SharePoint 不会验证请求获取的权限是否已授予。因此,在批准或拒绝权限请求前,请务必先检查已在租户中授予的权限。

  • 若要批准特定的权限请求,请运行 spo serviceprincipal permissionrequest approve 命令,同时指定要批准的权限请求的 ID。

    注意

    如果试图批准已授予的权限请求,将会看到错误消息。

  • 若要拒绝权限请求(如果请求获取的权限已授予,或请求违反组织策略),请运行 spo serviceprincipal permissionrequest deny 命令,同时指定要拒绝的权限请求的 ID。

    注意

    如果 SharePoint 框架应用程序发出的权限请求遭拒,并不会阻止应用程序部署到应用程序目录中和安装到网站中。

  • 若要查看已在租户中授予的权限,请运行 spo serviceprincipal grant list 命令。 对于每个已授予权限,此命令都会显示以下信息:

    • ObjectId:已授予权限的唯一标识符。
    • Resource:已授予对其访问权限的资源。
    • ResourceId:已授予对其访问权限的资源服务主体的 objectId。
    • Scope:资源应用程序应在 OAuth 2.0 访问令牌中获取的范围声明值。
  • 若要撤销之前授予的权限,请运行 spo serviceprincipal grant revoke 命令。 在 grantId 参数中,指定要撤销的已授予权限的 objectId,可通过运行 spo serviceprincipal grant list 命令获取它。

    注意

    撤销权限不会触发对应用程序目录或所有已部署应用程序的任何更改。 撤销权限的唯一后果是,租户中的任何应用程序将无法连接到已撤销对其权限的资源。

使用 AadHttpClient 连接到 Azure AD 应用程序

自版本 1.4.1 起,SharePoint 框架简化了连接到受 Azure AD 保护的 API 的过程。 使用全新的 AadHttpClient,可以轻松连接到受 Azure AD 保护的 API,而无需自行实现身份验证和授权。

在内部,AadHttpClient 使用 SharePoint Online 客户端扩展性服务主体来获取有效的访问令牌,从而利用Microsoft 标识平台身份验证库实现 Azure AD OAuth 流。 “SharePoint Online 客户端扩展性”服务主体由 Microsoft 预配,包含在所有 Office 365 租户的 Azure AD 中。

  1. 若要在 SharePoint 框架解决方案中使用 AadHttpClient,请在主 Web 部件文件中添加以下 import 子句:

    import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http';
    
  2. 获取新的 AadHttpClient 实例,同时将资源作为参数传递给要连接到的资源:

    export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
      public render(): void {
        // ...
    
        this.context.aadHttpClientFactory
          .getClient('https://contoso.azurewebsites.net')
          .then((client: AadHttpClient): void => {
            // connect to the API
          });
      }
    
      // ...
    }
    

    注意

    每个 AadHttpClient 实例都与特定资源关联,这就是为什么需要为要连接到的每个资源新建客户端实例的原因所在。

  3. 为资源实例化 AadHttpClient 后,可以发出 Web 请求来与 API 通信;在此示例中,API 返回订单列表,由项目中其他位置定义的自定义“订单”接口表示:

    export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
      public render(): void {
        // ...
    
        this.context.aadHttpClientFactory
          .getClient('https://contoso.azurewebsites.net')
          .then((client: AadHttpClient): void => {
            client
              .get('https://contoso.azurewebsites.net/api/orders', AadHttpClient.configurations.v1)
              .then((response: HttpClientResponse): Promise<Order[]> => {
                return response.json();
              })
              .then((orders: Order[]): void => {
                // process data
              });
          });
      }
    
      // ...
    }
    

注意事项

处理 Web API 权限时,应遵循下面的一些注意事项。

通过 SharePoint 框架解决方案请求获取权限

目前,只能通过 SharePoint 框架解决方案请求获取其他权限。 当包含权限请求的解决方案包 (.sppkg) 部署到应用程序目录时,请求就会启动。 请求启动后,全局或 SharePoint 管理员就可以批准或拒绝请求了。

已授予权限应用于所有解决方案

虽然对 Azure AD 资源的权限是由 SharePoint 框架解决方案请求获取,但只要授予,权限就会应用于整个租户,并可供相应租户中的任何解决方案使用。

删除解决方案不会撤销权限

删除最初请求获取特定权限的解决方案不会撤销已授予权限。 管理员必须通过 SharePoint 框架应用程序请求手动撤销已授予权限。

撤销之前授予的权限不会导致之前颁发的访问令牌无效。

撤销之前授予的权限不会导致颁发给用户的访问令牌无效。 相反,这些访问令牌将在到期前一直有效。

权限请求不影响解决方案部署

无论管理员是拒绝还是批准授予解决方案请求获取的权限,解决方案都可以在网站中部署和使用。 生成需要其他权限的解决方案时,不得假定请求获取的权限已授予。

控制 SharePoint Online 客户端服务主体

通过 Web API 请求授予的所有权限都与“SharePoint Online 客户端扩展性”Azure AD 应用程序一起存储。 如果管理员不希望开发人员在解决方案中使用 Web API 请求模型、MSGraphClientAadHttpClient,可以通过 PowerShell 运行 Disable-SPOTenantServicePrincipal cmdlet,禁用 “SharePoint Online 客户端扩展性”服务主体。

若要重新启用服务主体,可以运行 Enable-SPOTenantServicePrincipal cmdlet。 也可以通过适用于 Microsoft 365 的 CLI 运行 spo serviceprincipal set 命令,启用和禁用“SharePoint Online 客户端扩展性”服务主体。