惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
Last Week in AI
Last Week in AI
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
The Cloudflare Blog
罗磊的独立博客
月光博客
月光博客
N
Netflix TechBlog - Medium
C
Check Point Blog
Microsoft Security Blog
Microsoft Security Blog
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
Jina AI
Jina AI
J
Java Code Geeks

博客园 - 霖雨

用PowerShell命令一次启动多个前后端应用 Visual Studio Code中配置Cline 解决MSSQLLocalDB连接失败的问题 使用App Registration 访问 SharePoint Online (一) SharePoint Online 文档库的还原功能 SharePoint Online 快捷方式功能 SharePoint Online 文档库的收藏功能 使用豆包开发SharePoint Framework项目 Power Automate 还原误删的 Flow PowerShell 获取已删除的 Automate Flow PowerShell 新建 Address Book Policy PowerShell 批量添加用户到组 PowerShell 批量下载 SharePoint Online 文档 PowerShell 清空 SharePoint Online 列表数据 PowerShell 新建 SharePoint Online 列表 PowerShell 获取 SharePoint Online 站点信息 PowerShell 启用 SharePoint Online CDN SharePoint Online 定时发布页面 SharePoint Online 页面诊断 Microsoft Whiteboard 的使用 SharePoint Online 网站配置时区 SharePoint Online 集成 Viva Connections SharePoint Online 分区模板 SharePoint Online 嵌入 Power BI 报表
使用App Registration 访问 SharePoint Online (二)
霖雨 · 2026-07-12 · via 博客园 - 霖雨

  前言

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

  正文

  直接上代码吧,如下图:

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,搞了好久好久,发现不行,但是用证书可以,大家参考吧。