【问题标题】:UseStatusCodePages() position in request pipeline请求管道中的 UseStatusCodePages() 位置
【发布时间】:2021-07-19 09:26:57
【问题描述】:

我有一个带有承载身份验证的 aspnet 核心 MVC 项目(令牌是从另一个 api 接收的)。

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, config =>
{
    config.Authority = configuration["TokenServerUrl"];
    config.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            context.Token = context.HttpContext.Request.Cookies["access_token"];
            return Task.CompletedTask;
        },
    };
});

我需要在未经授权的请求时重定向到登录页面,所以我找到了 UseStatusCodePages() 方法。 奇怪的是 UseStatusCodePages 必须放在授权中间件之前:

app.UseStatusCodePages(context => 
{
    var response = context.HttpContext.Response;
            
    if (response.StatusCode == (int)HttpStatusCode.Unauthorized ||
        response.StatusCode == (int)HttpStatusCode.Forbidden)
    {
        response.Redirect("/Account/Login");
    }
    return Task.CompletedTask;
});
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        "default",
        "{controller=Home}/{action=Index}/{id?}");
});

我想,UseAuthentication中间件返回401然后就可以处理了。那么如果 UseStatusCodePages 中间件放在 UseAuthentication 之前,它如何处理 401 代码呢?如果我将 UseStatusCodePages 放在 UseAuthorization 之后 - 它根本不会被调用,这很奇怪。任何人都可以解释这种行为吗?

【问题讨论】:

    标签: asp.net-core


    【解决方案1】:

    中间件不在另一个中间件之前或之后运行;相反,中间件围绕其他中间件运行。

    在您的示例设置中,中间件是这样执行的:

    Request
    | StatusCodePages
    | ⮩ (next)
        | StaticFiles
        | ⮩ (next)
            | Routing
            | ⮩ (next)
                | Authentication
                | ⮩ (next)
                    | Authorization
                    | ⮩ (next)
                        | Endpoints
                        | (serve request)
                        | ⮨
                    | ⮨
                | ⮨
            | ⮨
        | ⮨
    | ⮨
    

    每个中间件都有机会做一些工作,然后它调用管道中的 next 中间件。一旦下一个中间件完成,中间件就有机会在内部中间件完成后进行一些处理。

    对于 StatusCodePages 中间件,它所做的是执行下一个中间件,一旦完成,它会查看生成的状态代码并运行您的自定义处理程序,该处理程序有机会修改响应。

    如果您交换了顺序,那么 StatusCodePages 中间件将在产生 401/403 状态代码的中间件内部运行,因此无法对其结果采取行动。 p>

    【讨论】:

    • 谢谢。我以为它是一个管道,但实际上它是一个调用堆栈
    猜你喜欢
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    相关资源
    最近更新 更多