具有不同根的ASP.Net核心反向代理

时间:2017-07-25 18:50:02

标签: asp.net-core reverse-proxy

我在代理ASP.NET Core MVC应用程序时遇到问题。

我的应用程序在localhost:5000上的Kestrel上运行,而我的Apache 2.4反向代理正在localhost:80上运行。我想代理从localhost:80/testlocalhost:5000

的所有请求

以下是代理的httpd.conf部分:

...
<Location "/test">
   ProxyPass "http://localhost:5000"
   ProxyPassReverse "http://localhost:5000"
</Location>
...

代理有效,但所有链接都已损坏。就像我有一个锚点链接到名为HomeController的控制器并使用操作About一样,从代理返回的链接是localhost/Home/About而不是localhost/test/Home/About。主机是正确的,它是缺少的上下文根test

处理此问题的最佳做法是什么? ASP.NET Core中的配置是否指定了上下文根,以便TagHelpers将其考虑在内?或者它是Apache ProxyPass中的一个配置来重写链接(真的不是这个的忠实粉丝)?

2 个答案:

答案 0 :(得分:13)

问题是Web应用程序不知道子路径/test,因此在您的情况下,它只会像在根路径上直接调用一样进行响应。

ASP.NET Core有一个PathBase的概念来解决这个问题。 PathBase本质上是请求的URI路径的一部分,它将被视为路径的固定部分。每当框架内的组件生成URL时,它都会考虑当前的PathBase,并确保将其作为所有生成路径的前缀。

默认情况下,PathBase将为空,这取决于您的反向代理的配置,以说明您应如何设置PathBase

UsePathBaseMiddleware

内置UsePathBaseMiddleware可用于为传入请求临时配置PathBase。此中间件的工作方式基本上是它将检查请求是否以可接受的路径前缀开头,如果是,则该前缀将从Path移动到PathBase

您可以使用UsePathBaseExtensions.UsePathBase扩展名方法激活此功能。只需使用您想要使用的基本路径调用该方法作为Startup的Configure方法中的第一个方法:

public void Configure(IApplicationBuilder app)
{
    app.UsePathBase("/test");

    // all the other middlewares
    app.UseStaticFiles();
    app.UseMvc();
    // …
}

由于中间件只会在传入请求路径中看到PathBase前缀时调整/test,因此您需要确保反向代理实际上包含该前缀。因此,您必须调整Apache配置以包含该路径:

<Location "/test">
   ProxyPass "http://localhost:5000/test"
   ProxyPassReverse "http://localhost:5000/test"
</Location>

请注意,UsePathBaseMiddleware不会阻止应用程序在没有前缀的情况下使用。所以你可以在有和没有基本路径的情况下使用它,它将正确适应。

自定义中间件

如果您不想调整反向代理配置以在转发的请求中包含路径,那么您将无法使用UsePathBaseMiddleware。相反,您必须在那里添加自己非常简单的中间件:

public void Configure(IApplicationBuilder app)
{
    app.Use((context, next) =>
    {
        context.Request.PathBase = "/test";
        return next();
    });

    // all the other middlewares
    app.UseStaticFiles();
    app.UseMvc();
    // …
}

这会将/test设置为传入请求的常量 PathBase。因此,实际传入的请求不必包含它,这意味着您可以保留反向代理配置(而不是转发/test路径)。但是,这也意味着与根据传入请求动态设置UsePathBaseMiddleware的{​​{1}}不同,现在对应用程序的所有请求都将需要该路径,而不管他们是否通过反向代理。

答案 1 :(得分:1)

代理正在丢弃请求路径信息,因此您必须通过执行以下操作重新引入它:

app.Use((context,next)=&gt; {   context.Request.PathBase =“/ test”;   return next(); });

这与UsePathBase的作用不同,它将路径段从Path的开头移动到PathBase的末尾。 https://github.com/aspnet/HttpAbstractions/blob/49b447d6265f0de44304b1b887cbdd3227cb038d/src/Microsoft.AspNetCore.Http.Abstractions/Extensions/UsePathBaseMiddleware.cs#L54