ASP.Net Core Reverse Proxy with different root
for .net core you could add this
app.UsePathBase(basePath);
app.UseRouting();
The proxy is dropping request path information so you must re-introduce it by doing something like this:
app.Use((context, next) =>
{
context.Request.PathBase = "/test";
return next();
});
This is different from what UsePathBase does, it moves path segments that are still there from the start of Path to the end of PathBase.
https://github.com/aspnet/HttpAbstractions/blob/49b447d6265f0de44304b1b887cbdd3227cb038d/src/Microsoft.AspNetCore.Http.Abstractions/Extensions/UsePathBaseMiddleware.cs#L54
The problem is that the web application does not know about the subpath /test
, so in your case, it will just respond as if it was called directly at the root path.
ASP.NET Core has a concept of a PathBase
to remedy this. The PathBase
is essentially a part of the request’s URI path that will be considered as a fixed part of the path. Whenever a component within the framework generates an URL, it will take the current PathBase
into account and make sure to include that as a prefix to all generated paths.
By default, the PathBase
will be empty, and it depends on the configuration of your reverse proxy to say how you should set up the PathBase
.
UsePathBaseMiddleware
There is the built-in UsePathBaseMiddleware which can be used to temporarily configure the PathBase
for an incoming request. The way this middleware works is basically that it will check whether the request starts with an accepted path prefix and if it does, that prefix will be moved from the Path
into the PathBase
.
You can activate this using the UsePathBaseExtensions.UsePathBase
extension method. Just call the method as the very first thing in your Startup’s Configure
method with the base path you want to use:
public void Configure(IApplicationBuilder app)
{
app.UsePathBase("/test");
// all the other middlewares
app.UseStaticFiles();
app.UseMvc();
// …
}
Since the middleware will only adjust the PathBase
when it sees the /test
prefix within the path of incoming requests, you need to make sure that the reverse proxy actually includes that prefix. So you would have to adjust your Apache configuration to include that path:
<Location "/test">
ProxyPass "http://localhost:5000/test"
ProxyPassReverse "http://localhost:5000/test"
</Location>
Note that the UsePathBaseMiddleware will not prevent the application from working without that prefix. So you can actually use it both with and without the base path, and it will correctly adapt.
Custom middleware
If you do not want to adjust your reverse proxy configuration to include the path within the forwarded request, then you won’t be able to use the UsePathBaseMiddleware
. Instead, you will have to add your own very simple middleware there:
public void Configure(IApplicationBuilder app)
{
app.Use((context, next) =>
{
context.Request.PathBase = "/test";
return next();
});
// all the other middlewares
app.UseStaticFiles();
app.UseMvc();
// …
}
This will set /test
as a constant PathBase
for incoming requests. So the actually incoming request does not have to include it, which means you can leave your reverse proxy configuration as it is (and not forward the /test
path there). However, that also means that unlike with the UsePathBaseMiddleware
where the PathBase
was set dynamically depending on the incoming request, now all requests to the application will require that path, regardless of whether they go through the reverse proxy or not.