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

Blazor Server集成Entra ID获取AccessToken遇MsalUiRequiredException问题

.NET 8 Blazor Server + Microsoft.Identity.Web 令牌获取异常解决

问题根源

IDE重启应用后,服务器端的会话令牌缓存被清空,但客户端浏览器的认证Cookie仍有效。此时用户处于已认证状态,但服务器端没有对应的令牌缓存条目,调用TokenAcquisition.GetAccessTokenForUserAsync时,MSAL无法找到可用账户,触发MsalUiRequiredException。

解决方案

1. 捕获异常并触发重新认证

在令牌获取逻辑中捕获MsalUiRequiredException,调用MSAL的内置方法触发重新登录,重新填充令牌缓存:

protected override async Task OnInitializedAsync()
{
    var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
    User = authState.User.FindFirst(c => c.Type == System.Security.Claims.ClaimTypes.Name)?.Value
           ?? authState.User.FindFirst(c => c.Type == "name")?.Value;

    if (authState.User.Identity.IsAuthenticated)
    {
        string[] scopes = { "User.Read" };
        try
        {
            var token = await TokenAcquisition.GetAccessTokenForUserAsync(scopes);
            // 后续令牌使用逻辑
        }
        catch (MsalUiRequiredException ex)
        {
            // 触发重新认证,自动填充令牌缓存
            await TokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeaderAsync(scopes, ex);
        }
    }
}

2. 改用持久化分布式令牌缓存

内存会话缓存会随应用重启丢失,改用分布式缓存(开发环境可用内存版,生产建议用Redis等持久化方案):

// 注册分布式内存缓存(开发环境)
builder.Services.AddDistributedMemoryCache();

// 替换会话令牌缓存为分布式缓存
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("EntraID"))
    .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
    .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
    .AddDistributedTokenCaches(); // 替换原AddSessionTokenCaches

3. 同步Cookie与缓存的生命周期

确保认证Cookie的过期时间与会话缓存一致,避免Cookie有效但缓存失效的情况:

builder.Services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme,
    options =>
    {
        options.Events.OnRedirectToAccessDenied =
            context =>
            {
                context.Response.Redirect("/AccessDenied");
                return context.Response.CompleteAsync();
            };
        // 同步Cookie过期时间与会话超时
        options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
        options.SlidingExpiration = true;
    });

4. 确认中间件顺序

保持中间件执行顺序正确,UseSession必须在UseAuthentication之前:

app.UseHttpsRedirection();
app.UseSession(); // 先初始化会话
app.UseStaticFiles();
app.UseAntiforgery();
app.UseAuthentication();
app.UseAuthorization();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:47:02