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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:48:04