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

.NET Core 7中AddDefaultIdentity替换AddIdentity后跳转异常问题

问题分析与解决方案

核心问题定位

你遇到的现象本质是跳转逻辑未正确触发到Home控制器的Index方法,导致ActionFilter拿到的上下文仍是原登录控制器。结合代码变更和现象,主要有以下几个关键问题点:

1. 跳转代码的致命错误

你在RedirectToLocal的else分支中错误使用了Redirect方法:

RedirectToActionResult res = Redirect("Index", "Home");

Redirect方法的第二个参数是URL锚点(fragment),而非控制器名,这段代码实际生成的是类似/当前控制器路径/Index#Home的URL,并未跳转到Home控制器。之前用AddIdentity时可能因为路由fallback或其他配置巧合生效,但换用AddDefaultIdentity后路由规则严格执行,导致跳转失败。

2. AddDefaultIdentity与手动认证配置冲突

AddDefaultIdentity内部已经默认配置了CookieAuthenticationDefaults.AuthenticationScheme作为默认认证方案,你手动添加的AddAuthentication配置会与内置配置产生冲突,导致认证中间件顺序或上下文异常。

3. 基控制器与ActionFilter的执行顺序问题

如果基控制器重写OnActionExecutionAsync时未调用base.OnActionExecutionAsync,会破坏过滤器管道的正常执行,导致上下文传递异常。


分步解决方案

1. 修正跳转逻辑

将错误的跳转代码替换为正确的RedirectToAction方法:

private ActionResult RedirectToLocal(string returnUrl)
{
    if (returnUrl != null && (Url.IsLocalUrl(returnUrl)
        || returnUrl.Contains(Host)))
    {
        return Redirect(returnUrl);
    }
    else
    {
        // 正确跳转到Home控制器的Index方法
        return RedirectToAction("Index", "Home");
    }
}

2. 清理认证配置冲突

移除手动添加的AddAuthentication配置,因为AddDefaultIdentity已经内置了Cookie认证的默认配置:

// 移除这段冲突代码
// services.AddAuthentication(options =>
// {
//     options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// })

如果需要自定义Cookie认证选项,可以通过AddDefaultIdentity的配置扩展实现:

services.AddDefaultIdentity<ApplicationUser>(o =>
{
    o.User.RequireUniqueEmail = true;
    // 可在此添加自定义Cookie选项
    o.SignIn.RequireConfirmedAccount = true;
    o.Cookie.HttpOnly = true;
})
.AddRoles<ApplicationRole>()
.AddEntityFrameworkStores<SocraticMembershipsContext>()
.AddUserStore<ApplicationUserStore>()
.AddRoleStore<ApplicationRoleStore>()
.AddUserManager<ApplicationUserManager>()
.AddRoleManager<ApplicationRoleManager>()
.AddSignInManager<ApplicationSignInManager>()
.AddDefaultTokenProviders(); // 建议取消注释,令牌功能在密码重置等场景需要

3. 确保基控制器正确调用基类方法

检查基控制器的OnActionExecutionAsync实现,必须调用base.OnActionExecutionAsync来维持过滤器管道的正常执行:

public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
    // 你的自定义逻辑代码
    
    // 必须调用基类方法,否则会中断过滤器管道
    await base.OnActionExecutionAsync(context, next);
}

4. 验证中间件顺序

确保Program.cs中的中间件顺序正确:

var app = builder.Build();

// ... 其他配置

app.UseRouting();

// 认证中间件必须在授权中间件之前
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

额外排查点

  • 确认NavigationAttribute已在DI容器中注册(因为使用了ServiceFilter):
    builder.Services.AddScoped<NavigationAttribute>();
    
  • 检查浏览器控制台的网络请求,确认跳转是否返回302并正确指向/Home/Index。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:11:05