Azure函数(.NET 8隔离模式)调用Graph API获取OneDrive文件报错求助
问题原因及解决方法
错误原因
你使用的是应用权限认证(ClientSecretCredential),而graphClient.Me.Drive调用的/me端点仅支持委托权限流(即用户登录的场景),应用身份没有"当前用户"的概念,因此触发该错误。
解决步骤
1. 配置正确的应用权限
在Azure AD管理中心给你的应用注册添加应用权限(而非委托权限):
- 所需权限:
Files.Read.All(读取所有用户的OneDrive文件)或Files.ReadWrite.All(如果需要修改) - 必须点击授予管理员同意,确保权限生效
2. 修改Graph API调用逻辑
应用权限模式下,需明确指定要访问的用户(OneDrive属于特定用户),替换Me为具体的用户ID或用户邮箱,然后获取该用户的Drive,再遍历目标文件夹的子项。
修正后的完整代码
private static async Task<GraphServiceClient> GetAuthenticatedGraphClient() { var tenantId = Environment.GetEnvironmentVariable("TenantId"); var clientId = Environment.GetEnvironmentVariable("ClientId"); var clientSecret = Environment.GetEnvironmentVariable("ClientSecret"); var scopes = new[] { "https://graph.microsoft.com/.default" }; var options = new ClientSecretCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud, }; var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options); var graphClient = new GraphServiceClient(clientSecretCredential, scopes); return graphClient; } public async Task Run([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer) { _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); var txtSourceFolder = Environment.GetEnvironmentVariable("txtSourceFolder"); // 替换为目标用户的邮箱或ID,建议通过环境变量配置 var targetUserEmail = Environment.GetEnvironmentVariable("TargetUserEmail"); var graphClient = await GetAuthenticatedGraphClient(); // 获取目标用户的OneDrive var userDrive = await graphClient.Users[targetUserEmail].Drive.GetAsync(); _logger.LogInformation($"Got user drive ID: {userDrive.Id}"); // 获取目标文件夹下的所有子项(文件和子文件夹) var folderItems = await graphClient.Drives[userDrive.Id] .Items["root"] .ItemWithPath(txtSourceFolder) .Children .GetAsync(); if (folderItems?.Value != null) { foreach (var item in folderItems.Value) { _logger.LogInformation($"Item: {item.Name}, Type: {item.Folder != null ? "Folder" : "File"}"); // 如果需要获取文件内容,可调用:await graphClient.Drives[userDrive.Id].Items[item.Id].Content.GetAsync(); } } if (myTimer.ScheduleStatus is not null) { _logger.LogInformation($"Next timer schedule at: {myTimer.ScheduleStatus.Next}"); } }
补充说明
- 需在Azure函数的环境变量中新增
TargetUserEmail,设置为要访问OneDrive的用户邮箱(如user@contoso.com) - 如果要访问的是SharePoint站点的文档库,可替换为
graphClient.Sites["站点ID"].Drive的方式调用 - 务必确认应用权限已完成管理员同意授予,否则会触发权限不足的错误
内容的提问来源于stack exchange,提问作者A.L
相关产品推荐
相关产品推荐

