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

ASP.NET Core 6 MVC如何实现除登录页外全站密码保护?

解决ASP.NET Core 6 MVC集成Identity后的重定向循环问题

你遇到的localhost redirected you too many times.错误,核心原因是未正确排除登录页的身份验证拦截,导致未登录用户被重定向到登录页后,又被验证逻辑再次拦截并重定向,形成无限循环。以下是具体的修复方案和正确配置步骤:


一、放弃自定义中间件,使用官方授权机制(推荐)

ASP.NET Core Identity本身配套了成熟的认证/授权中间件,无需手动编写自定义中间件来实现全局授权拦截,官方方案更稳定且避免循环问题:

1. 确保Identity服务配置正确

在Program.cs中添加Identity服务(需提前配置好继承IdentityDbContext的数据库上下文):

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
    .AddEntityFrameworkStores<ApplicationDbContext>();

2. 配置中间件顺序(关键)

中间件顺序直接影响认证/授权逻辑的执行,必须严格遵循以下顺序:

var app = builder.Build();

// 环境相关中间件
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

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

app.UseRouting();

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

// 默认路由映射
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

// 映射Identity的Razor页面(如果使用Identity内置UI)
app.MapRazorPages();

app.Run();

3. 标记允许匿名访问的页面

在登录页对应的控制器动作上添加[AllowAnonymous]特性,全局其他页面默认需要授权:

public class AccountController : Controller
{
    // 登录页允许匿名访问
    [AllowAnonymous]
    public IActionResult Login(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }

    // 登录提交接口同样允许匿名
    [AllowAnonymous]
    [HttpPost]
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        // 登录逻辑...
    }
}

// 其他控制器全局添加授权要求
[Authorize]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

二、如果坚持使用自定义中间件的修复方案

若你一定要用自定义中间件实现拦截,必须在逻辑中排除登录页的路径,避免循环:

1. 修改自定义中间件逻辑

public class AuthMiddleware
{
    private readonly RequestDelegate _next;
    private readonly string _loginPath = "/Account/Login"; // 匹配你的登录页路由

    public AuthMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 跳过登录页的身份检查
        if (!context.Request.Path.StartsWithSegments(_loginPath) && !context.User.Identity.IsAuthenticated)
        {
            // 重定向到登录页,并携带原请求地址以便登录后返回
            var returnUrl = context.Request.Path + context.Request.QueryString;
            context.Response.Redirect($"{_loginPath}?returnUrl={Uri.EscapeDataString(returnUrl)}");
            return;
        }

        await _next(context);
    }
}

2. 正确注册中间件

确保中间件在UseAuthentication之后、UseAuthorization之前注册:

app.UseAuthentication();
// 添加自定义中间件
app.UseMiddleware<AuthMiddleware>();
app.UseAuthorization();

关键注意事项

  • 无论使用哪种方案,都必须保证登录页本身不被身份验证逻辑拦截,这是解决循环重定向的核心。
  • 若使用Identity内置的登录UI(AddDefaultIdentity配合MapRazorPages),需确保/Identity/Account/Login路径被允许匿名,Identity默认已处理此逻辑,但需注意路由冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:50:31