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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:45:34