【问题标题】:ASP.Net Core Reverse Proxy with different root具有不同根的 ASP.Net Core 反向代理
【发布时间】:2017-12-31 20:35:12
【问题描述】:

我在代理 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 中的配置来重写链接(真的不喜欢这个)?

【问题讨论】:

  • 你好@Curlyfire 我正在努力在 Windows 平台上的 Apache 上托管 MVC 核心。您对非 Windows 进行的上述测试。

标签: asp.net-core reverse-proxy


【解决方案1】:

问题是 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();
    // …
}

由于中间件只会在传入请求路径中看到/test 前缀时调整PathBase,因此您需要确保反向代理确实包含该前缀。因此,您必须调整 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 不同,PathBase 是根据传入请求动态设置的,现在 所有 对应用程序的请求将需要该路径,无论它们是否通过是否反向代理。

【讨论】:

  • 这正是我想要的。我还能够根据方法名称在 github 上找到讨论的问题。 github.com/aspnet/Hosting/issues/815
  • 这仍然是这样做的方法吗?我遇到了同样的问题,但 UsePathBase 中间件似乎没有改变任何东西......?
  • @kspearrin 是的,这仍然是要走的路。如果您启用路径库,那么您的应用程序应该可以在 https://example.com/https://example.com/test/ 获得。
  • 该应用程序在“/”处运行,但我在“/app”处对其进行反向代理。它似乎总是认为它仍然以'/'的形式运行。
  • 如果你直接打开网站而不是通过反向代理,它是否有效?如果它以这种方式工作,那么您的反向代理可能配置错误。
【解决方案2】:

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

app.Use((context, next) =>
{
  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

【讨论】:

猜你喜欢
  • 2017-02-18
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 2020-01-07
  • 1970-01-01
  • 2018-08-08
  • 2017-09-22
  • 1970-01-01
相关资源
最近更新 更多