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

