.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
相关产品推荐
相关产品推荐

