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

