Azure Developer CLI (azd) 是一种开源工具,可加速在 Azure 中预配和部署应用资源。
本文使用 适用于 SharePoint Webhook 的 Azure 函数应用公共模板 部署连接到 SharePoint Online 租户的 Azure 函数应用,注册和管理 Webhook,以及处理来自 SharePoint 的通知。
先决条件
- Node.js 20
- Azure Functions Core Tools
- Azure Developer CLI (azd)
- 信任 SharePoint 租户相同的Microsoft Entra ID目录的 Azure 订阅
在 Azure 中预配资源所需的权限
运行 azd 的 帐户必须至少具有以下角色才能成功预配资源:
- Azure 角色 参与者:创建所需的所有资源
- Azure 角色基于角色访问控制管理员:分配角色 (来访问存储帐户和 Application Insights) 函数应用的托管标识
在 Azure 中部署函数应用
从空的本地 (根) 文件夹运行 azd init :
azd init --template azd-functions-sharepoint-webhooks
在出现提示时输入环境名称,例如 spofuncs-quickstart 。 在 azd 中,环境用于维护应用的唯一部署上下文。
打开文件基础结构/main.parameters.json,并设置变量
TenantPrefix
和siteRelativePath
以匹配 SharePoint 租户。查看 有关管理环境变量 以管理 azd 环境变量的文章。
最后,运行 azd up 命令以生成应用、在 Azure 中预配资源并部署应用包。
向函数应用授予对 SharePoint Online 的访问权限
对 SharePoint 的身份验证是使用 DefaultAzureCredential
完成的,因此使用的凭据取决于函数应用是在本地运行还是在 Azure 中运行。
如果从未听说过 DefaultAzureCredential
,则应通过参考适用于 JavaScript 的 Azure 标识客户端库中的凭据链中的使用 DefaultAzureCredential 部分来熟悉其概念。
使用其托管标识
DefaultAzureCredential
将使用托管标识对 SharePoint 进行身份验证。 这可能是函数应用服务的现有系统分配托管标识,也可以是用户分配的托管标识。
本教程假定使用系统分配的托管标识。
授予 SharePoint API 权限网站。已选择托管标识
导航到函数应用Azure 门户>选择“标识”,并记下系统分配的托管标识的“对象 (主体) ID”。
注意
在本教程中,它是 d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8。
然后,使用以下脚本之一向此标识授予“仅应用”权限 网站。在 SharePoint API 上选择:
重要
以下脚本至少需要委派的权限 AppRoleAssignment.ReadWrite.All
(需要管理员同意)
使用 Microsoft Graph PowerShell SDK
# This script requires the modules Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns, which can be installed with the cmdlet Install-Module below:
# Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns -Scope CurrentUser -Repository PSGallery -Force
Connect-MgGraph -Scope "Application.Read.All", "AppRoleAssignment.ReadWrite.All"
$managedIdentityObjectId = "d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity
$scopeName = "Sites.Selected"
$resourceAppPrincipalObj = Get-MgServicePrincipal -Filter "displayName eq 'Office 365 SharePoint Online'" # SPO
$targetAppPrincipalAppRole = $resourceAppPrincipalObj.AppRoles | ? Value -eq $scopeName
$appRoleAssignment = @{
"principalId" = $managedIdentityObjectId
"resourceId" = $resourceAppPrincipalObj.Id
"appRoleId" = $targetAppPrincipalAppRole.Id
}
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityObjectId -BodyParameter $appRoleAssignment | Format-List
在 Bash 中使用 az cli
managedIdentityObjectId="d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity
resourceServicePrincipalId=$(az ad sp list --query '[].[id]' --filter "displayName eq 'Office 365 SharePoint Online'" -o tsv)
resourceServicePrincipalAppRoleId="$(az ad sp show --id $resourceServicePrincipalId --query "appRoles[?starts_with(value, 'Sites.Selected')].[id]" -o tsv)"
az rest --method POST --uri "https://graph.microsoft.com/v1.0/servicePrincipals/${managedIdentityObjectId}/appRoleAssignments" --headers 'Content-Type=application/json' --body "{ 'principalId': '${managedIdentityObjectId}', 'resourceId': '${resourceServicePrincipalId}', 'appRoleId': '${resourceServicePrincipalAppRoleId}' }"
授予托管标识对 SharePoint 网站的有效访问权限
导航到 “企业应用程序> ”,将 “应用程序类型 筛选器”设置为 “托管标识> ”,选择托管标识并记下其 应用程序 ID。
注意
本教程为 3150363e-afbe-421f-9785-9d5404c5ae34。
然后,使用以下脚本之一授予它“仅应用 管理 ”权限, (在特定 SharePoint 网站上注册 Webhook) 所需的最低权限:
重要
用于运行这些脚本的应用注册必须至少具有以下权限:
- 图形 API (中的委托权限 Application.ReadWrite.All 需要管理员同意)
- SharePoint API (中的委托权限 AllSites.FullControl 需要管理员同意)
使用 PnP PowerShell
Connect-PnPOnline -Url "https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME" -Interactive -ClientId "YOUR_PNP_APP_CLIENT_ID"
Grant-PnPAzureADAppSitePermission -AppId "3150363e-afbe-421f-9785-9d5404c5ae34" -DisplayName "YOUR_FUNC_APP_NAME" -Permissions Manage
在 Bash 中使用 m365 cli
targetapp="3150363e-afbe-421f-9785-9d5404c5ae34"
siteUrl="https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME"
m365 spo site apppermission add --appId $targetapp --permission manage --siteUrl $siteUrl
调用函数应用
出于安全原因,在 Azure 中运行时,函数应用需要应用密钥才能传入查询字符串参数 代码。 应用密钥位于函数应用服务的 “应用密钥” 页中。
大多数 HTTP 函数采用可选参数 TenantPrefix
和 siteRelativePath
。 如果未指定,则使用应用环境变量中的值。
下面是 PowerShell 中用于调用函数应用的示例脚本:
# Edit those variables to match your environment
$funchost = "YOUR_FUNC_APP_NAME"
$code = "YOUR_HOST_KEY"
$listTitle = "YOUR_SHAREPOINT_LIST"
$notificationUrl = "https://${funchost}.azurewebsites.net/api/webhooks/service?code=${code}"
# List all the webhooks registered on a list
Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/list?code=${code}&listTitle=${listTitle}"
# Register a webhook in a list
Invoke-RestMethod -Method POST -Uri "https://${funchost}.azurewebsites.net/api/webhooks/register?code=${code}&listTitle=${listTitle}¬ificationUrl=${notificationUrl}"
# Show this webhook registered on a list
Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/show?code=${code}&listTitle=${listTitle}¬ificationUrl=${notificationUrl}"
# Remove the webhook from a list
# Step 1: Call the function /webhooks/show to get the webhook id
$webhookId = $(Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/show?code=${code}&listTitle=${listTitle}¬ificationUrl=${notificationUrl}").Id
# Step 2: Call the function /webhooks/remove and pass the webhook id
Invoke-RestMethod -Method POST -Uri "https://${funchost}.azurewebsites.net/api/webhooks/remove?code=${code}&listTitle=${listTitle}&webhookId=${webhookId}"
清理 Azure 中的资源
可以通过运行 命令 azd down 来删除此项目在 Azure 中创建的所有资源。
或者,可以删除资源组,该资源组默认具有 azd 环境的名称。