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

ASP.NET Core MVC调用Microsoft Graph API获取用户请求挂起问题解决

解决ASP.NET Core MVC中Graph API请求无限挂起的问题

问题描述

在ASP.NET Core MVC应用中调用Microsoft Graph API获取当前用户信息时,graphServiceClient.Me.GetAsync()请求无限挂起,无法完成。已完成的配置包括:

  • 应用在Microsoft Identity平台注册,已授予User.Read委派API权限
  • 控制器及GraphServiceClient创建代码如下:

控制器代码

[HttpGet]
public async Task<IActionResult> Index()
{
    try
    {
        var graphServiceClient = GetGraphServiceClient();
        var entraIDUser = await graphServiceClient.Me.GetAsync();

        return View();

    }
    catch (Exception ex)
    {
        _logger.LogError("An error occured when trying to return Index page: " + ex.Message);

        return StatusCode(500, "An error occured when trying to return Index page");
    }
}

GetGraphServiceClient方法代码

private GraphServiceClient GetGraphServiceClient()
{
    var scopes = new[] { "User.Read" };
    var tenantId = _configuration.GetValue<string>("AzureAd:TenantId");
    var clientId = _configuration.GetValue<string>("AzureAd:ClientId");

    var options = new DeviceCodeCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
        ClientId = clientId,
        TenantId = tenantId,

        DeviceCodeCallback = (code, cancellation) =>
        {
            Console.WriteLine(code.Message);
            return Task.FromResult(0);
        },
    };

    var deviceCodeCredential = new DeviceCodeCredential(options);

    var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);

    return graphClient;
}

解决方案

1. 替换DeviceCodeCredential为Web应用适配的认证方式

DeviceCodeCredential是为桌面/设备类应用设计的交互式认证方案,在ASP.NET Core MVC这类Web应用场景下完全不适用——它会等待用户在终端输入设备码完成认证,但Web应用没有终端交互环境,直接导致请求无限挂起。

正确的做法是使用当前已登录用户的访问令牌调用Graph API,修改GetGraphServiceClient方法:

private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IConfiguration _configuration;
private readonly ILogger<YourController> _logger;

// 构造函数注入依赖
public YourController(IHttpContextAccessor httpContextAccessor, IConfiguration configuration, ILogger<YourController> logger)
{
    _httpContextAccessor = httpContextAccessor;
    _configuration = configuration;
    _logger = logger;
}

private GraphServiceClient GetGraphServiceClient()
{
    // 获取当前登录用户的access_token
    var accessToken = _httpContextAccessor.HttpContext.GetTokenAsync("access_token").Result;
    
    return new GraphServiceClient(
        new DelegateAuthenticationProvider(requestMessage =>
        {
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            return Task.CompletedTask;
        }));
}

2. 配置Web应用的Azure AD认证流程

在Program.cs中完善认证配置,添加Graph API权限支持:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi(new[] { "User.Read" })
    .AddInMemoryTokenCaches();

// 注册HttpContextAccessor,用于获取当前请求上下文
builder.Services.AddHttpContextAccessor();

3. 验证权限配置

  • 确认应用注册中User.Read权限为委派权限
  • 如果是多租户应用或需要管理员级访问,需确保权限已获得租户管理员同意;单租户场景下,用户首次登录时会自动授权该权限

4. 检查异步调用逻辑

确保控制器方法始终使用await处理异步操作,避免同步阻塞(原代码中的await graphServiceClient.Me.GetAsync()是正确的,无需修改)

内容的提问来源于stack exchange,提问作者StanSm789

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:21:09