使用App Registration 访问 SharePoint Online (二)

  前言

  我们上一篇介绍了准备环境,这一篇直接介绍如何写代码吧

  正文

  直接上代码吧,如下图:

using System.Security.Cryptography.X509Certificates;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.SharePoint.Client;
using PnP.Framework;

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
    .Build();

var tenantId = configuration["AzureAd:TenantId"]!;
var clientId = configuration["AzureAd:ClientId"]!;
var certPath = configuration["AzureAd:CertificatePath"]!;
var certPassword = configuration["AzureAd:CertificatePassword"] ?? "";
var siteUrl = configuration["SharePoint:SiteUrl"]!;
var listName = configuration["SharePoint:ListName"]!;

Console.WriteLine($"Site: {siteUrl}, List: {listName}");
Console.WriteLine($"Certificate: {certPath}");
Console.WriteLine();

// 1. Load certificate from .pfx file
if (!System.IO.File.Exists(certPath))
{
    Console.WriteLine($"ERROR: Certificate file not found: {certPath}");
    return;
}

var cert = System.Security.Cryptography.X509Certificates.X509CertificateLoader.LoadPkcs12FromFile(certPath, certPassword, X509KeyStorageFlags.Exportable);
Console.WriteLine($"Certificate loaded: {cert.Subject}");
Console.WriteLine($"Has Private Key: {cert.HasPrivateKey}");
Console.WriteLine($"Thumbprint: {cert.Thumbprint}");
Console.WriteLine();

// 2. Get access token using certificate
var siteUri = new Uri(siteUrl);
var scope = $"{siteUri.Scheme}://{siteUri.Host}/.default";
Console.WriteLine($"Acquiring token for: {scope}");

var credential = new ClientCertificateCredential(tenantId, clientId, cert);
var token = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(new[] { scope }));
Console.WriteLine($"Token acquired, expires: {token.ExpiresOn}");
Console.WriteLine();

// 3. Create CSOM context with PnP.Framework
var authManager = new AuthenticationManager();
using var ctx = authManager.GetAccessTokenContext(siteUrl, token.Token);

// 4. Load web info
var web = ctx.Web;
ctx.Load(web, w => w.Title);
await ctx.ExecuteQueryAsync();
Console.WriteLine($"Web: {web.Title}");
Console.WriteLine();

// 5. Load list items
var list = ctx.Web.Lists.GetByTitle(listName);
var items = list.GetItems(CamlQuery.CreateAllItemsQuery(100));
ctx.Load(items, i => i.Include(
    item => item.Id,
    item => item["Title"]));
await ctx.ExecuteQueryAsync();

Console.WriteLine($"Total items: {items.Count}");
foreach (var item in items)
{
    Console.WriteLine($"  ID: {item.Id}, Title: {item["Title"]}");
}

  下面是配置

{
  "AzureAd": {
    "TenantId": "412bb5e1-d687-4320-bf4e-b8f81048446d",
    "ClientId": "bda3bd11-0fca-4399-8dc4-f4facf187c20",
    "CertificatePath": "C:\\temp\\spoapp.pfx",
    "CertificatePassword": "test!"
  },
  "SharePoint": {
    "SiteUrl": "https://test.sharepoint.com/sites/test",
    "ListName": "问题跟踪表"
  }
}

  在下面是结果

image

  结束语

  比较坑的是,一开始一直想用secret,搞了好久好久,发现不行,但是用证书可以,大家参考吧。

posted @ 2026-07-12 12:46  霖雨  阅读(7)  评论(0)    收藏  举报