.NET Core 自定义Middleware如何实现与Controller一致的Authorize授权校验
问题原因说明
你之前在UseWhen分支里重复注册的UseAuthentication、UseAuthorization不生效,是因为全局的身份校验已经在进入分支前执行完成,而默认的授权中间件仅会对匹配到的、带[Authorize]特性的MVC/API端点触发授权逻辑,自定义中间件不属于端点范畴,所以全局授权中间件不会主动为它做授权校验。
推荐规范实现方案
官方推荐通过注入IAuthorizationService的方式实现和[Authorize]特性完全一致的授权逻辑,支持自定义授权策略、指定认证方案等能力,和控制器的授权行为完全对齐:
1. 改造自定义中间件
public class MyCustomMiddleware { private readonly RequestDelegate _next; private readonly IAuthorizationService _authorizationService; // 定义和[Authorize(AuthenticationSchemes = "Bearer")]等价的授权策略 private readonly AuthorizationPolicy _authPolicy = new AuthorizationPolicyBuilder("Bearer") .RequireAuthenticatedUser() .Build(); public MyCustomMiddleware(RequestDelegate next, IAuthorizationService authorizationService) { _next = next; _authorizationService = authorizationService; } public async Task InvokeAsync(HttpContext context) { // 执行和控制器[Authorize]特性完全一致的授权校验 var authResult = await _authorizationService.AuthorizeAsync(context.User, context, _authPolicy); if (!authResult.Succeeded) { // 未授权时返回和控制器一致的状态码 context.Response.StatusCode = context.User.Identity.IsAuthenticated ? StatusCodes.Status403Forbidden : StatusCodes.Status401Unauthorized; return; } // 授权通过后执行自定义业务代码 // 你的业务逻辑写在这里 await _next(context); } }
2. 简化中间件注册逻辑
不需要在UseWhen分支重复注册身份、授权中间件,直接保留全局配置即可:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); // 全局身份、授权中间件保留 app.UseAuthentication(); app.UseAuthorization(); app.UseWhen(context => GetCondition(context), appBuilder => { // 直接注册自定义中间件即可 appBuilder.UseMiddleware<MyCustomMiddleware>(); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
轻量场景可选方案
如果只需要判断登录状态不需要复杂授权规则,也可以直接在分支注册条件里做判断,不需要改造中间件:
app.UseWhen(context => GetCondition(context) && context.User.Identity.IsAuthenticated, appBuilder => { appBuilder.UseMiddleware<MyCustomMiddleware>(); });
内容的提问来源于stack exchange,提问作者Tahir
相关产品推荐
相关产品推荐

