Home > Software design >  Kestrel :: Bind to multiple HTTP and HTTPS urls through appsettings.json
Kestrel :: Bind to multiple HTTP and HTTPS urls through appsettings.json

Time:09-16

I have a ASP.NET Core service build in .Net 5 which uses Kestrel as edge server. The service needs to listen on multiple domains on HTTP protocol - e.g. http://foo:12912 & http://bar:12912 and HTTPS protocol like http://foo:443 & http://bar:443.

I know we can do with UseUrls in Program.cs.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseUrls("http://foo:12912", "http://bar:12912");
            });
}

However - given that Kestel has evolved so much - there should be a way to configure this from json config itself. All config examples that I could find only do for a single url like

"Kestrel": {
  "EndPoints": {
    "Http": {
      "Url": "http://foo:12912"
    },
    "Https": {
      "Url": "https://foo:443"
    }
  }
}

The property name is also url and not urls so my assumption is that it only supports single url and not multiple. Is my expectation correct or am I missing something?

CodePudding user response:

Basically, you just need to put semicolons in your Url section from below is excerpt from https://andrewlock.net/5-ways-to-set-the-urls-for-an-aspnetcore-app/

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:38327",
      "sslPort": 44310
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "TestApp": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

CodePudding user response:

In development you can use the launchSettings.json like this:

"WebApplication1": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }

Notice that the applicationUrl takes a list separated by semicolons.

In production usually kestrel would be fronted by a reverse proxy.

Like NGINX configured as a reverse proxy which would handle the SSL and the kestrel would not need to expose ssl ports since all the security should be handled by the actual webserver and not by kestrel.

Kestrel is not designed to be exposed to the internet. But it is actually a minimalistic wrapper for a web application.

That being said.... However there is way to do what you want.

Way 1 use multiple endpoints: Notice you can add many endpoints with different json keys.

 {
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "<certificate password>"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

Way 2 use the ASPNETCORE_URLS or DOTNET_URLS environment variables and assign a semicolon separated list of urls.

Way 3 set the "urls" key in the appsettings.json whic also uses a semicolon separated list of urls.

{
  "Urls": "http://localhost:9999;https://someotherdomain.com"  
}

Further documentation and limitations of each method are here

Configure endpoints for the ASP.NET Core Kestrel web server

  • Related