You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:11:15