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

ASP.NET 8.0 Blazor Server表单提交后跳转至登录页问题

ASP.NET 8.0 Blazor Server表单提交后身份验证丢失问题

问题详情

我正在开发一个ASP.NET 8.0 Blazor Server应用,采用Microsoft Identity Framework Core实现授权功能,仅在用户登录成功后加载菜单项。我在NavMenu.razor和Home.razor组件中使用了如下授权逻辑:

<AuthorizeView>
    <Authorized>
        ........
    </Authorized>
    <NotAuthorized>
        <Components.Account.Pages.Login>

        </Components.Account.Pages.Login>
    </NotAuthorized>
</AuthorizeView>

应用启动时会要求用户登录,登录成功后侧边栏sidebar会显示菜单项,但当我在任意页面执行表单提交操作后,所有菜单项消失,页面跳转回登录页。以下是我的program.cs代码:

using GetTutorsOnline.Components;
using GetTutorsOnline.Components.Account;
using GetTutorsOnline.Data;
using GTO.IModels.IModelRepos;
using GTO.Infrastructure.Data;
using GTO.Infrastructure.Repositories;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents().AddInteractiveServerComponents();

builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<IdentityUserAccessor>();
builder.Services.AddScoped<IdentityRedirectManager>();
builder.Services.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>();

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
    .AddIdentityCookies();

var conStr = builder.Configuration.GetConnectionString("DifriPediaSQLDb");
builder.Services.AddDbContextFactory<GTODbContext>(options => options.UseSqlServer(conStr));
builder.Services.AddDbContext<IdentityContext>(options => options.UseSqlServer(conStr));

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddIdentityCore<GTOAppUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<IdentityContext>()
    .AddSignInManager()
    .AddDefaultTokenProviders();

builder.Services.AddSingleton<IEmailSender<GTOAppUser>, IdentityNoOpEmailSender>();

builder.Services.AddScoped<ISubjectNameRepo, SubjectNameRepo>();
builder.Services.AddScoped<IRegionRepo, RegionRepo>();
builder.Services.AddScoped<IAssessmentMonthRepo, AssessmentMonthRepo>();
builder.Services.AddScoped<IELevelRepo, ELevelRepo>();
builder.Services.AddScoped<ITeacherRepo, TeacherRepo>();
builder.Services.AddScoped<ICoordinatorRepo, CoordinatorRepo>();
builder.Services.AddScoped<IManagerRepo, ManagerRepo>();
builder.Services.AddScoped<IStudentRepo, StudentRepo>();
builder.Services.AddScoped<IParentRepo, ParentRepo>();
builder.Services.AddScoped<IEvaluationTweekRepo, EvaluationTweekRepo>();
builder.Services.AddScoped<ISubjectAllocationRepo, SubjectAllocationRepo>();
builder.Services.AddScoped<IDayNameRepo, DayNameRepo>();


var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

//app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.MapAdditionalIdentityEndpoints();

app.Run();

解决方案

1. 恢复路由中间件

取消注释program.cs中的app.UseRouting();,Blazor Server依赖路由中间件来正确处理组件路由和身份验证上下文传递,缺失会导致身份状态在表单提交后丢失:

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

2. 替换NotAuthorized块中的Login组件嵌入方式

直接在AuthorizeView的NotAuthorized块中嵌入Login组件会干扰身份状态管理,改用模板自带的RedirectToLogin组件实现登录跳转:

<NotAuthorized>
    <RedirectToLogin />
</NotAuthorized>

该组件会自动保存当前页面路径,登录成功后跳转回原页面,同时避免身份状态冲突。

3. 检查防伪令牌验证

Blazor Server表单提交必须通过防伪令牌验证,若令牌缺失或验证失败会触发身份验证失败。确保:

  • app.UseAntiforgery();位于UseStaticFiles()之后、UseAuthentication()之前
  • 表单使用Blazor交互式提交(@onsubmit绑定)而非原生HTML表单提交,示例:
<form @onsubmit="HandleSubmit">
    <!-- 表单字段 -->
    <button type="submit">提交</button>
</form>

@code {
    private async Task HandleSubmit()
    {
        // 业务逻辑处理
    }
}

4. 验证IdentityRevalidatingAuthenticationStateProvider行为

IdentityRevalidatingAuthenticationStateProvider会定期重新验证用户身份,若其实现逻辑有误,可能在表单提交后错误地将用户标记为未授权。检查该类的ValidateAuthenticationStateAsync方法,确保仅在必要时(如用户信息变更)触发重新验证,而非每次请求都执行。

5. 调整身份Cookie配置

确保身份验证Cookie的有效期和滑动过期设置合理,避免表单提交后Cookie意外过期:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies(options =>
{
    options.ApplicationCookie.Configure(cookie =>
    {
        cookie.ExpireTimeSpan = TimeSpan.FromHours(8);
        cookie.SlidingExpiration = true;
        cookie.HttpOnly = true;
        cookie.SecurePolicy = CookieSecurePolicy.Always;
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:35:00