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

ASP.NET Core 8.0 MVC中OpenID Connect异常对接UseExceptionHandler中间件

解决ASP.NET Core 8.0 MVC认证异常无法传递到通用错误页的问题

核心思路

认证中间件的OnAuthenticationFailed事件属于认证流程内部的异常处理逻辑,默认不会自动将异常传递给全局UseExceptionHandler中间件。要实现异常的统一处理,需手动将异常注入到HttpContext的异常特性中,让全局异常中间件能够识别并处理。

具体实现步骤

1. 在OnAuthenticationFailed中注入异常到HttpContext特性

在认证服务配置(以JWT认证为例)里,修改OnAuthenticationFailed的处理逻辑,把异常添加到HttpContext的IExceptionHandlerFeature特性中:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 其他认证配置项...
        options.Events = new JwtBearerEvents
        {
            OnTokenValidated = context =>
            {
                // 示例:Token验证阶段抛出异常
                throw new UnauthorizedAccessException("Token验证失败:权限不足");
            },
            OnAuthenticationFailed = context =>
            {
                // 将异常注入到HttpContext的异常特性,供全局异常中间件识别
                context.HttpContext.Features.Set<IExceptionHandlerFeature>(new ExceptionHandlerFeature
                {
                    Error = context.Exception,
                    Path = context.HttpContext.Request.Path
                });

                // 不直接重定向,让请求继续流转到全局异常中间件
                return Task.CompletedTask;
            }
        };
    });

2. 确保UseExceptionHandler中间件顺序正确

在Program.cs中,UseExceptionHandler必须注册在UseAuthentication和UseAuthorization之前,这样才能捕获后续认证流程中产生的异常:

var app = builder.Build();

// 全局异常处理中间件,需放在认证、授权中间件之前
app.UseExceptionHandler("/Main/Error");

// 认证与授权中间件
app.UseAuthentication();
app.UseAuthorization();

// 路由配置等其他中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

3. 在错误页控制器中获取异常

在MainController的Error方法里,通过IExceptionHandlerPathFeature获取异常并填充ErrorViewModel:

public class MainController : Controller
{
    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        var viewModel = new ErrorViewModel
        {
            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier,
            Exception = exceptionFeature?.Error,
            Path = exceptionFeature?.Path
        };

        return View(viewModel);
    }
}

关键注意事项

  • 不要在OnAuthenticationFailed中直接执行重定向,否则会跳过全局异常中间件的处理流程,无法复用ErrorViewModel的统一逻辑。
  • 通过HttpContext.Features.Set注入IExceptionHandlerFeature是核心操作,这与全局异常捕获的逻辑保持一致,能让UseExceptionHandler正确识别异常。
  • 中间件顺序不能颠倒,UseExceptionHandler必须优先于认证、授权中间件注册,否则无法捕获认证阶段的异常。

内容的提问来源于stack exchange,提问作者m.t.bennett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:29:52