ASP.NET Core 2.0中如何在自定义中间件中请求身份验证
当然可以实现!在ASP.NET Core的请求管道中,中间件的执行顺序完全由你注册的顺序决定,只要配置得当,就能让你的自定义认证中间件在业务处理中间件之前完成认证逻辑。下面一步步来拆解实现方式:
核心思路:控制中间件注册顺序
ASP.NET Core的请求管道是按注册顺序依次执行的(请求进入时先执行先注册的中间件,响应返回时反向执行)。所以要让认证逻辑先于业务处理,关键是把认证相关的中间件注册在你的业务中间件之前。
步骤1:正确配置认证服务与中间件
首先确保你已经正确注册了自定义认证方案,然后在Configure方法中把UseAuthentication放在业务中间件之前:
1.1 注册认证服务(在ConfigureServices中)
services.AddAuthentication(options => { // 可以设置默认认证/挑战方案,或者依赖自定义SchemeProvider动态选择 options.DefaultAuthenticateScheme = "YourCustomAuthScheme"; options.DefaultChallengeScheme = "YourCustomAuthScheme"; }) // 注册你的自定义认证方案与处理程序 .AddScheme<YourCustomAuthOptions, YourCustomAuthHandler>( "YourCustomAuthScheme", options => { // 这里配置你的自定义认证选项,比如密钥、有效期等 }); // 如果有自定义AuthenticationSchemeProvider,记得注册它 services.AddScoped<IAuthenticationSchemeProvider, CustomAuthenticationSchemeProvider>();
1.2 配置中间件顺序(在Configure中)
var app = builder.Build(); // 其他中间件(比如静态文件、路由等) app.UseRouting(); // 认证中间件必须放在业务中间件之前 app.UseAuthentication(); // 如果需要授权逻辑,也可以加上UseAuthorization app.UseAuthorization(); // 注册你的业务处理中间件 app.UseMiddleware<YourBusinessMiddleware>(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
步骤2:在业务中间件中手动触发认证(可选)
默认情况下,UseAuthentication会尝试使用默认方案对请求进行认证,但如果你的场景需要更灵活的控制(比如根据请求动态选择方案,或者强制在业务逻辑前完成认证),可以在业务中间件中手动调用认证服务:
public class YourBusinessMiddleware { private readonly RequestDelegate _next; private readonly IAuthenticationService _authenticationService; // 注入IAuthenticationService public YourBusinessMiddleware(RequestDelegate next, IAuthenticationService authenticationService) { _next = next; _authenticationService = authenticationService; } public async Task InvokeAsync(HttpContext context) { // 手动触发认证: // - 传具体方案名:指定用你的自定义方案认证 // - 传null:让自定义SchemeProvider根据请求动态选择方案 var authResult = await _authenticationService.AuthenticateAsync(context, null); if (authResult.Succeeded) { // 认证成功,将用户信息绑定到HttpContext.User context.User = authResult.Principal; // 执行你的业务逻辑,比如根据用户身份处理请求 } else { // 认证失败的处理逻辑,比如返回401 Unauthorized context.Response.StatusCode = StatusCodes.Status401Unauthorized; return; } // 传递请求到下一个中间件 await _next(context); } }
结合自定义AuthenticationSchemeProvider的场景
如果你已经实现了自定义AuthenticationSchemeProvider来根据URL选择不同的认证方案,那么在手动调用AuthenticateAsync时传null即可——IAuthenticationService会自动调用你的自定义Provider来确定当前请求应该使用的认证方案,完全适配你的动态路由需求。
与MVC过滤器方式的区别
你之前在MVC中使用AuthorizeFilter是在MVC过滤器管道中执行认证,而中间件是在更底层的请求管道中运行。两者的执行顺序是:请求先经过中间件管道,再进入MVC的过滤器管道。所以现在把认证逻辑移到中间件层,会比MVC过滤器更早执行,能覆盖所有请求(包括非MVC的API、静态文件请求等)。
内容的提问来源于stack exchange,提问作者Rython




