Blazor .NET 8 WASM使用Strawberry Shake注入访问令牌失败求助
问题解决:Blazor WASM中StrawberryShake注入访问令牌报错
错误原因
IAccessTokenProvider是Scoped生命周期的服务,但你在ConfigureHttpClient中使用的是根服务提供者(Singleton级别),根容器无法解析Scoped服务,这就是报错的核心原因。另外,ConfigureHttpClient仅在服务注册阶段执行一次,即使能获取令牌,也只会是启动时的静态令牌,无法处理后续令牌过期的问题。
解决方案
方案一:使用官方AccessTokenProviderMessageHandler(推荐)
微软提供了专门处理令牌的消息处理器,自动完成令牌获取、请求头注入和过期刷新:
builder.Services.AddMsalAuthentication(...); builder.Services.AddCascadingAuthenticationState(); builder.Services.AddAuthorizationCore(...); // 注册令牌消息处理器 builder.Services.AddTransient<AccessTokenProviderMessageHandler>(); builder.Services.AddGqlClient() .ConfigureHttpClient(client => { client.BaseAddress = new Uri($"{apiUrl}/graphql"); }) .AddHttpMessageHandler<AccessTokenProviderMessageHandler>(); // 绑定处理器
方案二:自定义StrawberryShake操作拦截器(精细控制场景)
如果需要更灵活的令牌逻辑,可创建自定义拦截器:
- 实现拦截器类:
public class AuthInterceptor : IOperationInterceptor { private readonly IAccessTokenProvider _tokenProvider; public AuthInterceptor(IAccessTokenProvider tokenProvider) { _tokenProvider = tokenProvider; } public async ValueTask OnCreateAsync(OperationInterceptorContext context) { var tokenResult = await _tokenProvider.RequestAccessToken(); if (tokenResult.TryGetToken(out var token)) { context.Request.Headers.Add("Authorization", $"Bearer {token.Value}"); } } }
- 注册并绑定拦截器:
builder.Services.AddMsalAuthentication(...); builder.Services.AddCascadingAuthenticationState(); builder.Services.AddAuthorizationCore(...); // 注册拦截器为Scoped生命周期 builder.Services.AddScoped<AuthInterceptor>(); builder.Services.AddGqlClient() .ConfigureHttpClient(client => { client.BaseAddress = new Uri($"{apiUrl}/graphql"); }) .AddOperationInterceptor<AuthInterceptor>(); // 添加拦截器
两种方案都能解决根容器无法解析Scoped服务的问题,且确保每次请求都能获取最新的有效令牌。
内容的提问来源于stack exchange,提问作者baouss
相关产品推荐
相关产品推荐

