ASP.NET Core 6.0 MVC集成IdentityServer4时404页面无法正常显示
问题:使用IdentityServer4时,访问不存在的URL被重定向到登录页而非预设的/not-found页面
我正在使用IdentityServer4处理用户身份验证,但当用户访问不存在的URL时,系统会将其重定向到登录页面,而非预设的/not-found页面。请问我遗漏了哪些配置?
Program.cs
// IdentityServer4 configurations builder.Services.AddAuthentication(options => { options.DefaultScheme = "cookies"; options.DefaultChallengeScheme = "oidc"; }).AddCookie("cookies", c => c.ExpireTimeSpan = TimeSpan.FromHours(8)) .AddOpenIdConnect("oidc", options => { options.Authority = builder.Configuration["ServiceUrls:IdentityApi"]; options.GetClaimsFromUserInfoEndpoint = true; options.ClientId = "WebClient"; options.ClientSecret = "secret"; options.ResponseType = "code"; options.ClaimActions.MapJsonKey("role", "role", "role"); options.ClaimActions.MapJsonKey("sub", "sub", "sub"); options.TokenValidationParameters.NameClaimType = "name"; options.TokenValidationParameters.RoleClaimType = "role"; options.Scope.Add("admin"); options.SaveTokens = true; }); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } //Hnadle unhandled exceptions 500 erros app.UseExceptionHandler("/server-error"); //Handle 404 erros app.Use(async (ctx, next) => { await next(); if (ctx.Response.StatusCode == 404 && !ctx.Response.HasStarted) { ctx.Request.Path = "/not-found"; await next(); } });
HomeController.cs
[HttpGet] [Route("not-found")] public IActionResult PageNotFound() { return View(); }
解决方案
1. 修正中间件顺序
你的404处理中间件位置错误,且缺少路由、认证授权和端点中间件的核心调用,导致请求逻辑混乱。正确的管道顺序如下:
// Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); // 初始化路由中间件 app.UseRouting(); // 添加认证、授权中间件(必须在路由之后,端点之前) app.UseAuthentication(); app.UseAuthorization(); // 异常处理逻辑保持在前面 app.UseExceptionHandler("/server-error"); // 将404处理中间件放在认证授权之后、端点中间件之前 app.Use(async (ctx, next) => { await next(); if (ctx.Response.StatusCode == 404 && !ctx.Response.HasStarted) { ctx.Request.Path = "/not-found"; await next(); } }); // 配置端点路由 app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
2. 允许匿名访问错误页面
如果你的控制器或全局配置了[Authorize]要求,即使重定向到/not-found也会触发登录跳转。需要给错误页面方法添加匿名访问权限:
[HttpGet] [Route("not-found")] [AllowAnonymous] // 添加此属性允许未认证用户访问 public IActionResult PageNotFound() { return View(); }
3. 全局授权策略的例外配置(如有)
如果你配置了全局强制认证的 fallback 策略,需要为错误页面路径添加例外规则:
// 服务配置中添加授权策略 builder.Services.AddAuthorization(options => { options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); // 定义匿名访问策略 options.AddPolicy("AllowAnonymous", policy => policy.AllowAnonymous()); });
然后在端点配置中指定错误页面使用匿名策略:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); // 给错误页面路由绑定匿名策略 endpoints.MapControllerRoute( name: "not-found", pattern: "/not-found") .RequireAuthorization("AllowAnonymous"); endpoints.MapControllerRoute( name: "server-error", pattern: "/server-error") .RequireAuthorization("AllowAnonymous"); });
内容的提问来源于stack exchange,提问作者Victor_Tlepshev
相关产品推荐
相关产品推荐

