C#中访问SharePoint的现代替代方案咨询(原PnP包已退役)
解决方案
方案1:使用PnP Framework的交互式认证(支持MFA)
这是官方推荐的PnPFramework替代方案,支持弹出登录窗口让用户完成账号认证(包含MFA验证),完全基于当前用户权限访问资源。
实现步骤:
- 安装NuGet包:
PnP.Framework - 替换原有代码为以下实现:
using Microsoft.SharePoint.Client; using PnP.Framework; using System.IO; string siteUrl = "https://xxx.sharepoint.com/teams/mypage"; string serverRelativePath = "/teams/mypage/Shared Documents/filename.xlsx"; string tempFileName = Path.Combine(Path.GetTempPath(), "filename.xlsx"); // 使用PnP官方公共客户端ID,无需自行注册Azure应用 var authProvider = new InteractiveAuthenticationProvider( siteUrl, "31359c7f-bd7e-475c-86db-fdb8c937548e" ); using (var context = new ClientContext(siteUrl)) { context.AuthenticationProvider = authProvider; // 获取目标文件 var file = context.Web.GetFileByServerRelativePath(serverRelativePath); context.Load(file); context.ExecuteQuery(); // 下载文件到本地临时路径 using (var fileStream = new FileStream(tempFileName, FileMode.Create)) { file.OpenBinaryStream().Result.CopyTo(fileStream); } }
说明:
- 公共客户端ID为PnP官方提供,无需向IT申请Azure应用注册
- 登录窗口自动适配公司MFA验证流程
- 若用户无目标文件访问权限,代码会抛出权限不足的异常,符合数据安全要求
方案2:Windows集成认证(域环境自动复用会话)
如果你的环境是域绑定的,且用户已通过MFA登录Windows会话,可尝试此方案,无需用户再次输入账号密码。
实现步骤:
- 安装NuGet包:
PnP.Framework、Microsoft.SharePointOnline.CSOM - 使用以下代码:
using Microsoft.SharePoint.Client; using PnP.Framework; using System.IO; using System.Net; string siteUrl = "https://xxx.sharepoint.com/teams/mypage"; string serverRelativePath = "/teams/mypage/Shared Documents/filename.xlsx"; string tempFileName = Path.Combine(Path.GetTempPath(), "filename.xlsx"); // 复用当前Windows用户的凭据 var credentials = CredentialCache.DefaultNetworkCredentials; var authProvider = new WindowsAuthenticationProvider(credentials); using (var context = new ClientContext(siteUrl)) { context.AuthenticationProvider = authProvider; var file = context.Web.GetFileByServerRelativePath(serverRelativePath); context.Load(file); context.ExecuteQuery(); using (var fileStream = new FileStream(tempFileName, FileMode.Create)) { file.OpenBinaryStream().Result.CopyTo(fileStream); } }
说明:
- 仅适用于域绑定环境,且Windows会话已通过MFA验证
- 全程无用户交互,自动复用当前登录凭据
- 同样基于用户权限控制,无权限文件无法访问
方案3:Microsoft Graph API(云原生现代方案)
Microsoft Graph是微软推荐的Office 365资源统一访问API,功能更全面,支持基于用户权限的访问。
实现步骤:
- 安装NuGet包:
Microsoft.Graph、Microsoft.Identity.Client - 代码实现:
using Microsoft.Graph; using Microsoft.Identity.Client; using System.IO; using System.Threading.Tasks; // 替换为你的站点ID和文件ID(可通过Graph API查询获取) string siteId = "your-site-id"; string driveItemId = "your-file-id"; string tempFileName = Path.Combine(Path.GetTempPath(), "filename.xlsx"); // 公共客户端ID,无需注册应用 string clientId = "31359c7f-bd7e-475c-86db-fdb8c937548e"; string[] scopes = new[] { "Files.Read" }; // 初始化MSAL客户端 var pca = PublicClientApplicationBuilder .Create(clientId) .WithRedirectUri("http://localhost") .Build(); // 获取用户访问令牌 var result = await pca.AcquireTokenInteractive(scopes) .WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount) .ExecuteAsync(); // 创建Graph服务客户端 var graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(requestMessage => { requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken); return Task.CompletedTask; })); // 下载文件到本地 var stream = await graphClient.Sites[siteId].Drive.Items[driveItemId].Content.Request().GetAsync(); using (var fileStream = new FileStream(tempFileName, FileMode.Create)) { await stream.CopyToAsync(fileStream); }
说明:
- 站点ID和文件ID可通过Graph API查询获取:
- 查询站点ID:调用
GET /sites/root:/teams/mypage - 查询文件ID:调用
GET /sites/{site-id}/drive/root:/Shared Documents/filename.xlsx
- 查询站点ID:调用
- 支持MFA验证,无权限文件会返回403错误
- 是长期迭代的优先选择,符合微软云服务的发展方向
注意事项
- 所有方案均严格基于当前用户权限控制文件访问,符合公司数据保护要求
- 优先推荐方案1,因为它是原有CSOM代码的最小改动替代,且得到PnP官方支持
- 若需完全自动化,在域环境下可尝试方案2,但需确认IT是否允许Windows集成认证访问SharePoint
内容的提问来源于stack exchange,提问作者Bedasy
相关产品推荐
相关产品推荐

