【问题标题】:Conditionally use custom middleware有条件地使用自定义中间件
【发布时间】:2017-08-06 21:14:12
【问题描述】:

我在 asp 中创建了我的自定义身份验证中间件。 net core 项目,并注册如下:

public class MyAuthenticationMidleware
{
    private readonly RequestDelegate _next;

    public ConnectAuthenticationMidleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (!UserIsAuthenticated())
        {
            context.Response.StatusCode = 401;
            return;
        }
        ...
        await _next.Invoke(context);
    }
}

public static class MyAuthenticationMidlewareExtensions
{
    public static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyAuthenticationMidleware>();
    }
}

在启动中:

    public void Configure(...)
    {
        app.UseStaticFiles();
        app.UseMyAuthentication();
        app.UseMvc();
    }

这可以正常工作 - 为每个请求运行身份验证中间件。如果用户未通过身份验证,则返回 401。否则会调用特定的 mvc 操作。

我试图做的是阻止身份验证中间件运行某些特定操作。我使用MapWhen方法创建了另一个扩展方法,使用如下:

public static class MyAuthenticationMidlewareExtensions
{
    public static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyAuthenticationMidleware>();
    }

    public static IApplicationBuilder UseMyAuthenticationWhen(this IApplicationBuilder builder, Func<HttpContext, bool> predicate)
    {
        return builder.MapWhen(predicate, applicationBuilder => applicationBuilder.UseMyAuthentication());
    }
}

public void Configure(...)
{
    app.UseStaticFiles();
    app.UseMyAuthenticationWhen(context => context.Request.Path != "xyz");
    app.UseMvc();
}

很遗憾,这并没有按预期工作。仅当路径与“xyz”不同时才调用中间件,但它似乎使整个链短路——没有调用特定于 mvc 的操作或过滤器。

可能我对MapWhen 的理解是不正确的。有什么办法可以得到我想要的结果吗?

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc


    【解决方案1】:

    MapWhen 在提供的谓词为真时创建一个新的管道分支,并且该分支重新加入您拥有UseMvc() 的主分支。

    您可以将扩展方法更改为使用UseWhen 而不是MapWhenUseWhen rejoins with the main pipeline 这样你的UseMvc() 仍然会被调用。

    注意:虽然上面的链接引用了 aspnet-contrib,但 UseWhen 扩展方法现在是 Microsoft.AspNetCore.Http.Abstractions 的一部分。

    这使您可以在您的 Configure 方法中保持 UseMvc() 显式,而不是隐藏在您的身份验证扩展方法中,因为它确实没有业务存在。

    【讨论】:

      【解决方案2】:

      MapWhen 用于分隔中间件管道。如果要将 mvc 用于分支管道,则需要单独添加。所以你应该在扩展方法中使用.UseMvc();,如下所示:

      public static IApplicationBuilder UseMyAuthenticationWhen(this IApplicationBuilder builder, Func<HttpContext, bool> predicate)
      {
          return builder.MapWhen(predicate, applicationBuilder =>
          { 
              applicationBuilder.UseMyAuthentication();
              applicationBuilder.UseMvc();
          });
      }
      

      但是我不会走你的路。对于身份验证中间件,我将实现自己的中间件,例如 Simple token based authentication/authorization in asp.net core for Mongodb datastore 并使用 Authorize 属性进行授权 mvc 操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-02
        • 1970-01-01
        • 2020-05-18
        相关资源
        最近更新 更多