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

.NET 6 Blazor Server 偶发登录循环问题求助

问题分析与修复方案

针对你遇到的Blazor Server偶发登录循环问题,结合代码细节和场景,核心问题集中在Graph API调用逻辑、组件生命周期时机、中间件配置这几个方面,以下是具体修复步骤:

1. 修复StateContainer中的Graph API调用错误

你的GetGraphUser方法存在两个关键问题:

  • 未调用.GetAsync()发起实际请求,导致代码逻辑无效
  • 未捕获异常,异常冒泡后触发认证重定向循环
  • 未验证用户认证状态就执行API调用

修改后的StateContainer.cs代码:

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

private readonly IConfiguration _config;
private readonly GraphServiceClient _graphServiceClient;
private readonly AuthenticationStateProvider _authStateProvider;
private UserDto _user;

// 注入AuthenticationStateProvider用于验证用户认证状态
public StateContainer(IConfiguration config, GraphServiceClient graphServiceClient, AuthenticationStateProvider authStateProvider)
{
    _config = config;
    _graphServiceClient = graphServiceClient;
    _authStateProvider = authStateProvider;
}

public async Task GetGraphUser()
{
    if (_user != null) return;

    var authState = await _authStateProvider.GetAuthenticationStateAsync();
    var user = authState.User;

    // 确保用户已完成认证再执行API调用
    if (!user.Identity.IsAuthenticated)
    {
        return;
    }

    try
    {
        // 补充.GetAsync()发起实际请求
        var graphUser = await _graphServiceClient.Me
            .Request()
            .Select(u => new { u.Id, u.EmployeeId, u.DisplayName, u.Mail })
            .GetAsync();

        _user = new UserDto
        {
            Id = graphUser.Id,
            EmployeeId = graphUser.EmployeeId,
            DisplayName = graphUser.DisplayName,
            Mail = graphUser.Mail
        };
    }
    catch (Exception ex)
    {
        // 记录日志,避免异常冒泡触发重定向
        // _logger.LogError(ex, "获取Graph用户信息失败");
    }
}

2. 调整MainLayout中API调用的时机

OnAfterRenderAsync会在组件每次渲染时执行,未加限制的调用会在用户未认证时触发无效请求,进而引发重定向循环。修改MainLayout.razor:

@inject StateContainer StateContainer
@inject AuthenticationStateProvider AuthStateProvider

@code {
    private bool _hasLoadedUser;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // 仅在第一次渲染且用户已认证时调用
        if (firstRender && !_hasLoadedUser)
        {
            var authState = await AuthStateProvider.GetAuthenticationStateAsync();
            if (authState.User.Identity.IsAuthenticated)
            {
                await StateContainer.GetGraphUser();
                _hasLoadedUser = true;
                StateHasChanged(); // 如需更新UI可添加
            }
        }
    }
}

3. 修正Program.cs中的中间件顺序

Blazor Server要求路由中间件必须在认证中间件之前,你的代码中缺少UseRouting(),这会导致认证逻辑无法正确处理请求:

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();

// 必须添加UseRouting,且在认证中间件之前
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

4. 额外排查点

  • Azure AD权限配置:确认User.Read权限已完成管理员/用户同意,ClientSecret未过期,Scopes配置与应用注册一致
  • Token缓存优化:如果是多实例部署,建议将AddInMemoryTokenCaches()替换为分布式缓存(如Redis),避免内存缓存不一致导致的token问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:43:20