使用Microsoft Graph认证通过直接链接下载SharePoint文档遇401问题求助
我正在把SharePoint CSOM应用迁移到Microsoft Graph API。原程序通过CSOM的用户名+密码凭证,借助System.Net.WebClient库下载SharePoint文档,但不清楚如何将Microsoft Graph的认证信息传递给SharePoint。
原CSOM代码
ClientContext SharePoint; remotePath = "https://{tenant}.sharepoint.com/sites/{site}/{list}/{filename}"; localPath = "C:\\temp\\{filename}"; //Authentication in CSOM using username/password not shown using (var client = new System.Net.WebClient()) { client.Credentials = SharePoint.Credentials; client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); client.DownloadFileTaskAsync(remotePath, localPath).Wait(); }
尝试的Microsoft Graph代码
var parentWindowHandle = new System.Windows.Interop.WindowInteropHelper(App.Current.MainWindow).Handle; var credentialOptions = new Azure.Identity.Broker.InteractiveBrowserCredentialBrokerOptions(parentWindowHandle) { ClientId = clientId, TenantId = tenantId, AuthorityHost = AzureAuthorityHosts.AzurePublicCloud, }; credential = new Azure.Identity.InteractiveBrowserCredential(credentialOptions); GraphServiceClient graphClient = new GraphServiceClient(credential); remotePath = "https://{tenant}.sharepoint.com/sites/{site}/{list}/{filename}"; localPath = "C:\\temp\\{filename}"; var tokenRequestContext = new Azure.Core.TokenRequestContext(new[] { "https://graph.microsoft.com/.default" }); token = await credential.GetTokenAsync(tokenRequestContext); using (var client = new System.Net.WebClient()) { client.Headers.Add("Authorization", "Bearer " + token.Token); client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); client.DownloadFileTaskAsync(remotePath, localPath).Wait(); }
遇到的问题
执行后返回401 UNAUTHORIZED:
- 尝试过获取
https://{tenant}.sharepoint.com/.default范围的token,结果相同; - 试过添加/移除
User-Agent: Other和X-FORMS_BASED_AUTH_ACCEPTED请求头,问题依旧; - 将
GetTokenAsync返回的token放入Postman测试,同样返回通用401。
当前已在应用中添加多个SharePoint相关API权限(如Sites.Read.All、Files.Read.All等)。
问题解决方法
1. 正确获取SharePoint资源的Token
直接访问SharePoint站点的文件URL,需要的是针对SharePoint资源的Token,而非Graph API的Token:
- 修改Token请求的范围为SharePoint的具体权限,而非
.default(.default多用于客户端凭证流,交互式认证推荐用具体权限):
var tokenRequestContext = new Azure.Core.TokenRequestContext(new[] { "https://{tenant}.sharepoint.com/Sites.Read.All", "https://{tenant}.sharepoint.com/Files.Read.All" }); token = await credential.GetTokenAsync(tokenRequestContext);
2. 推荐:直接使用Microsoft Graph API下载文件
既然迁移到Graph,建议遵循Graph的规范,通过Graph API端点获取文件内容,而非直接访问SharePoint原始URL:
// 1. 先获取站点ID(示例:通过站点路径获取) var site = await graphClient.Sites["{tenant}.sharepoint.com:/sites/{site}"].Request().GetAsync(); var siteId = site.Id; // 2. 获取文件对应的DriveItem ID(示例:从列表项获取) var listItem = await graphClient.Sites[siteId].Lists["{list-id}"].Items["{item-id}"].Request().Expand("driveItem").GetAsync(); var driveItemId = listItem.DriveItem.Id; // 3. 下载文件到本地 using (var stream = await graphClient.Sites[siteId].Drive.Items[driveItemId].Content.Request().GetAsync()) { using (var fileStream = new FileStream(localPath, FileMode.Create)) { await stream.CopyToAsync(fileStream); } }
3. 权限配置检查
确保应用已正确添加并授予Delegated类型的SharePoint权限(因为使用的是交互式认证流):
- 必需权限:
Sites.Read.All、Files.Read.All(根据需求选择读写权限) - 若为租户级权限,需完成管理员同意操作。
内容的提问来源于stack exchange,提问作者General Un-Co
相关产品推荐
相关产品推荐

