10

Is there a way in Kestrel to listen on 2 ports, e.g. 80 and 81, and specify different controllers for each port?

The scenario I have is that there are 2 controllers, one for the end user requests that would need token based authentication, and another controller is for machine based agents where I want to enforce client certificate based authentication.

Pang
  • 9,564
  • 146
  • 81
  • 122
schauhan
  • 531
  • 1
  • 5
  • 17
  • 1
    this kind of looks like the job of different web applications. Even if you could do this, almost everything such as cookies will be separated by default. I don't really see the point of having it as one application in this case – Neville Nazerane Apr 05 '18 at 19:50

3 Answers3

2

Not sure how far back this goes, but at least in .NET 6 you can use "Requires Host"

see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-6.0 and go to the section "Host matching in routes with RequireHost"

This allows you to do

[Host("*:81")]
public class My81Controller : Controller
{
  // stuff
}
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
1

Easiest way is after UseKestrel() add UseUrls("http://*:80", "http://*:80"), or simply set the environment variable ASPNETCORE_URLS="http://*:80;http://*:81"

Charles Thayer
  • 310
  • 2
  • 4
-1

I still feel like having two separate applications set up would be cleaner and easier to manage. You can always separate out anything you need (for instance, in your case, you can have different authentications set up) and you can share any kind of code between them, including controllers, services, and middlewares.

However, if you want to have it in the same application, you could try playing around with middlewares. From what I have seen, the MVC middleware only gives you access to the routing mainly, not ports. You can, however, add a middleware before UseMvc to reset a path. Something like this:

app.Use(async (context, next) => {
    if (context.Connection.LocalPort == 80)
        context.Request.Path = "/ports/80" + context.Request.Path.Value;
    await next();
});

You can look into areas to organize your controllers for routing after doing this. https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/areas. You will have to make sure all ports have this mapping to ensure that end users can't hardcode such paths.

InteXX
  • 6,135
  • 6
  • 43
  • 80
Neville Nazerane
  • 6,622
  • 3
  • 46
  • 79
  • 2
    Here is the use case for different controllers on different ports: health checks and metrics are placed on a service-port which is different then end-users API. Then this service port is not exposed outside a hosting cluster. – Michael Chudinov Mar 31 '21 at 20:33
  • Hi [Michael Chudinov](https://stackoverflow.com/users/2246724/michael-chudinov), where is the use case you pointed out ? – TrustworthySystems Nov 10 '21 at 16:08
  • `UseMvc` seems to have fallen out of favor under .NET 6. Where in the boilerplate `Program.cs` code of a new Blazor WASM project (sans `UseMvc`) would you suggest putting the `Use` call? – InteXX Mar 15 '22 at 11:03