Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core Reverse Proxy with different root

Tags:

I am having problems proxying an ASP.NET Core MVC app.

My app is running on Kestrel on localhost:5000 and my Apache 2.4 reverse proxy is running on localhost:80. I want to proxy all requests from localhost:80/test to localhost:5000

Here is the httpd.conf part for the proxy:

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

The proxy works, however all links are broken. Like if I have an anchor that links to a controller named HomeController with the action About, the link returned from the proxy is localhost/Home/About instead of localhost/test/Home/About. The host is correct, it's the context root test that is missing.

What is the best practice to handle this? Is it a configuration in ASP.NET Core to specify the context root so that TagHelpers will take it into account? Or is it a configuration in Apache ProxyPass to rewrite links (really not a big fan of this)?

like image 897
CurlyFire Avatar asked Jul 25 '17 18:07

CurlyFire


1 Answers

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.

like image 114
poke Avatar answered Sep 29 '22 01:09

poke