将提供程序托管的应用程序升级到 Azure Active Directory 应用程序

在 SharePoint 外接程序模型中,你用于创建所谓的提供程序托管的应用程序,这些应用程序是在 SharePoint Online 外部构建的应用程序,托管在第三方托管平台上(例如 Microsoft Azure),并且能够与 SharePoint Online 通信并通过 CSOM 或 REST API 使用其数据。

在 SharePoint Online 的新式开发环境中,可以注册 Azure Active Directory (Azure AD) 应用程序,并且仍可通过 CSOM、REST 或 Microsoft Graph 使用 SharePoint Online。 在本文中,可以找到有关如何将现有的提供程序托管的应用程序转换为新式 Azure AD 应用程序的详细信息。

重要

本文指的是所谓的 PnP 组件、示例和/或工具,它们是由提供支持的活动社区支持的开源资产。 没有来自 Microsoft 的官方支持渠道的开放源代码工具支持的 SLA。 但是,这些组件或示例使用的是 Microsoft 支持的现成 API 和 Microsoft 支持的功能。

如果愿意,可以watch以下视频,而不是阅读整篇文章,你仍然可以将其视为更详细的参考。

将提供程序托管的应用程序升级到 Azure Active Directory 应用程序

但是,应考虑到没有可以使用的转换工具,因此必须手动升级并稍微更改代码。 最简单的方法是创建新的应用程序,并部分迁移和调整现有代码。

创建新应用程序

从头开始,使用 Microsoft Visual Studio 2022 (或更高版本) ,使用 .NET 6.0 和 Razor 等方式创建新的 ASP.NET 核心 Web 应用程序。 创建此类应用程序时,可以选择使用“Microsoft 标识平台”作为身份验证层,如以下屏幕截图所示。

创建新的 ASP.NET Core应用程序时 Microsoft Visual Studio 2022 的 UI。已选择 .NET 6.0 LTS,并将“Microsoft 标识平台”作为所选身份验证层。

若要继续,必须同意安装“dotnet msidentity 工具”组件,该组件将用于配置“Microsoft 标识平台”身份验证,如以下屏幕截图所示。

Microsoft Visual Studio 2022 的 UI,提示安装“dotnet msidentity 工具”以配置身份验证。

必须提供有关用于身份验证的目标 Azure AD 租户的信息,并且能够在 Azure AD 中注册新应用程序。

使用 Azure AD 配置身份验证时 Microsoft Visual Studio 2022 的 UI。可以选择目标租户,并且可以注册将与应用程序关联的新 Azure AD 应用程序。

还可以按照将 SharePoint 应用程序从 Azure 访问控制 服务升级到 Azure Active Directory 并配置委派权限一文中的说明手动注册应用程序。

注意

有关 Azure AD、OAuth 2.0、委托令牌和应用程序令牌以及使用 SharePoint Online 的更多详细信息,请参阅 在 SharePoint Online 新式开发上下文中了解 Azure Active Directory 和 OAuth 2.0 一文。

如果要在 Azure AD 应用程序中使用 CSOM 或 SharePoint REST API,则必须使用 SharePoint Online 委派的权限配置 Azure AD 应用程序的 “API 权限” 部分,如以下屏幕截图所示。

Azure AD 应用程序的“API 权限”页,其中已授予 SharePoint Online 委托权限。

如果要通过 Microsoft Graph 使用 SharePoint Online 数据,可以配置 Microsoft Graph 委派权限。

现在,需要稍微更新 Web 应用程序的代码,以支持所谓的“增量同意”,这允许代码根据为应用程序本身配置的 API 权限动态请求 Azure AD 访问令牌以使用后端 API 或服务。

打开 Microsoft Visual Studio 生成的 Program.cs 文件,并更改以下行以更新依赖项注入的配置方式:

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

使用可在此处看到的新内容:

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

基本上,只需添加几个扩展方法即可配置对增量许可的支持和在内存中缓存令牌的支持。

现在,打开 Web 应用程序的 Index.cshtml.cs 文件, (或任何其他要自定义) 页面,并将 属性添加到 AuthorizeForScopes 继承自 PageModel的类。 这将使页面模型能够支持增量许可。

使用 SharePoint Online 数据

右键单击项目并选择“管理 NuGet 包”菜单项以转到包管理器。 现在,添加 “PnP 框架” 包,它将为你提供一组丰富的扩展和实用工具来使用 SharePoint Online。

现在,你已准备好实现或迁移自定义代码,以便通过 CSOM 或 REST API 使用 SharePoint Online。 在以下代码摘录中,可以看到示例页面模型的整个实现,该模型枚举目标网站的默认“共享文档”文档库中的文档。

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Identity.Web;
using Microsoft.SharePoint.Client;
using PnP.Framework;
using PnP.Framework.Utilities;

namespace AAD_Provider_Hosted_WebApp.Pages
{
    // Attribute required to have incremental consent
    [AuthorizeForScopes()]
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
        private readonly ITokenAcquisition _tokenAcquisition;
        private readonly IConfiguration _configuration;

        public List<Document> Documents { get; set; }

        public IndexModel(ILogger<IndexModel> logger,
            ITokenAcquisition tokenAcquisition,
            IConfiguration configuration)
        {
            _logger = logger;
            _tokenAcquisition = tokenAcquisition;
            _configuration = configuration;
        }

        public async Task OnGet()
        {
            await LoadSPODataAsync();
        }

        private async Task LoadSPODataAsync()
        {
            // Get the site URL from settings and determine the SPO tenant name
            var spoSiteUrl = _configuration["SPOSiteUrl"];
            var spoRootUrl = spoSiteUrl.Substring(0, spoSiteUrl.IndexOf("/", 9));

            // Get the access token for SPO
            var scopes = new[] { $"{spoRootUrl}/AllSites.Read" };
            var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes, user: HttpContext.User);
            var secureAccessToken = EncryptionUtility.ToSecureString(accessToken);

            // Build the secure ClientContext of CSOM via PnP Framework AuthenticationManager
            var am = AuthenticationManager.CreateWithAccessToken(secureAccessToken);
            using (var clientContext = am.GetContext(spoSiteUrl))
            {
                // User CSOM to retrieve files from the "Documents" document library
                var lib = clientContext.Web.Lists.GetByTitle("Documents");
                var docs = lib.GetItems(CamlQuery.CreateAllItemsQuery());

                clientContext.Load(docs);
                await clientContext.ExecuteQueryRetryAsync();

                // Map the documents to the Model
                this.Documents = new List<Document>();
                foreach (var d in docs)
                {
                    if (d["Title"] != null)
                    {
                        this.Documents.Add(new Document
                        {
                            Title = d["Title"]?.ToString(),
                            Link = $"{spoRootUrl}{d["FileRef"]?.ToString()}"
                        });
                    }
                }
            }
        }
    }
}

/// <summary>
/// Defines the model for a single Document item
/// </summary>
public record Document
{
    public string Title { get; set; }

    public string Link { get; set; }
}

核心部分在 LoadSPODataAsync 方法中定义,该方法使用实现 ITokenAcquisition 的服务实例获取访问令牌,以便通过 CSOM 或 REST API 使用 SharePoint Online。 请务必注意,如果要使用新式身份验证通过 CSOM 或 REST 使用 SharePoint Online 并提供 OAuth 访问令牌,则必须请求具有以下结构的权限范围的令牌:

https://[your-tenant-name].sharepoint.com/[permission-scope]

例如,如果要读取 SharePoint Online 数据,并且需要依赖 AllSites.Read 权限范围,则请求的实际权限范围将为 contoso.sharepoint.com) (:

https://contoso.sharepoint.com/AllSites.Read

从 Azure AD 获取有效的访问令牌后,可以依赖 AuthenticationManager PnP 框架的 类来检索 CSOM 的 , ClientContext 并使用目标 SharePoint Online 网站。 在这里,可以重复使用在旧的 SharePoint 外接程序模型提供程序托管应用程序中使用的 CSOM 代码。

有关本主题的其他信息,请参阅以下文档: