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

Blazor Server应用中能否将GraphServiceClient注入到Scoped服务中

错误原因分析

你遇到的No account or login hint was passed to the AcquireTokenSilent call报错,核心是自定义的UserService没有获取到当前已认证用户的上下文信息:

  • 微软官方的Microsoft Graph集成依赖当前请求的HttpContext中存储的已认证ClaimsPrincipal,来提取用户标识用于静默获取访问令牌
  • 你之前继承ComponentBase加[Authorize]的组件能正常运行,是因为[Authorize]特性会提前完成身份验证流程,将用户身份信息加载到当前请求上下文中,Blazor组件初始化时会自动把上下文传递给注入的GraphServiceClient,所以调用正常
  • 你的UserService既没有注入上下文访问能力,同时原来的同步调用逻辑也会导致上下文丢失,GraphServiceClient无法找到对应用户的令牌缓存,因此抛出报错。
解决方案

1. 注册IHttpContextAccessor服务

在Startup.cs的ConfigureServices方法中添加HttpContextAccessor的注册,用于获取当前请求的用户上下文:

public void ConfigureServices(IServiceCollection services)
{
    // 新增这一行
    services.AddHttpContextAccessor();

    // 保留你原有其他配置不变
    var initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
        .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
               .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
               .AddInMemoryTokenCaches();
    // ... 其他原有服务注册
}

2. 修改自定义UserService逻辑

注入IHttpContextAccessor获取当前用户,将所有Graph相关调用改为异步实现:

public class UserService
{
    private readonly GraphServiceClient _graphClient;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private User _cachedUser;

    public UserService(GraphServiceClient graphClient, IHttpContextAccessor httpContextAccessor)
    {
        _graphClient = graphClient;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<string> GetUserNameAsync()
    {
        var user = await GetCurrentUserAsync();
        return user?.DisplayName ?? string.Empty;
    }

    private async Task<User> GetCurrentUserAsync()
    {
        if (_cachedUser != null) return _cachedUser;
        
        // 校验当前请求是否有已认证的用户
        var currentPrincipal = _httpContextAccessor.HttpContext?.User;
        if (currentPrincipal == null || !currentPrincipal.Identity.IsAuthenticated)
        {
            return null;
        }

        try
        {
            _cachedUser = await _graphClient.Me.Request().GetAsync();
            return _cachedUser;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"获取用户信息失败: {ex.Message}");
            return null;
        }
    }
}

3. 正确调用UserService

在Blazor组件中调用时,必须添加[Authorize]特性确保上下文已认证,并且使用异步方式调用方法:

@page "/your-page"
@inject UserService UserService
@attribute [Authorize]

<p>当前登录用户:@_userName</p>

@code {
    private string _userName;

    protected override async Task OnInitializedAsync()
    {
        _userName = await UserService.GetUserNameAsync();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 21:36:02