Kestrelhttpserver: Determining Hosting Environment While Configuring Kestrel and UseHttps

Created on 31 Jan 2017  路  20Comments  路  Source: aspnet/KestrelHttpServer

In the ASP.NET Core Main method below, how can I determine the hosting environment, so I can switch between different certificate files for HTTPS?

public sealed class Program
{
    public static void Main(string[] args)
    {
        new WebHostBuilder()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseKestrel(
                options =>
                {
                    if ([Development Hosting Environment])
                    {
                        options.UseHttps("DevelopmentCertificate.pfx");
                    }
                    else
                    {
                        options.UseHttps("ProductionCertificate.pfx");
                    }
                })
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build()
            .Run();
    }
}
3 - Done enhancement

Most helpful comment

Another way to do this:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
            .UseKestrel()
            .ConfigureServices((context, services) =>
            {
                services.Configure<KestrelServerOptions>(options =>
                {
                    if (context.HostingEnvironment.IsDevelopment())
                    {
                        options.Listen(IPAddress.Loopback, 443, listenOptions =>
                        {
                            listenOptions.UseHttps("certificate.pfx", "password");
                        });
                    }
                });
            })
        .Build();

All 20 comments

It was just answered on another thread that I just saw: https://github.com/aspnet/Home/issues/1915#issuecomment-276133606

... and if you don't use command-line config, env var config, a config file, etc., then you can read the ASPNETCORE_ENVIRONMENT env var directly after you manually set it somehow.

It turns out you can use ConfigureServices to get hold of IHostingEnvironment like so:

public sealed class Program
{
    public static void Main(string[] args)
    {
        IHostingEnvironment hostingEnvironment = null;
        new WebHostBuilder()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureServices(
                services =>
                {
                    hostingEnvironment = services
                        .Where(x => x.ServiceType == typeof(IHostingEnvironment))
                        .Select(x => (IHostingEnvironment)x.ImplementationInstance)
                        .First();
                })
            .UseKestrel(
                options =>
                {
                    if (hostingEnvironment.IsDevelopment())
                    {
                        // Use a self-signed certificate to enable 'dotnet run' to work in development.
                        options.UseHttps("DevelopmentCertificate.pfx", "password");
                    }
                })
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build()
            .Run();
    }
}

It really feels like this should be easier.

Assigning to @cesarbs for investigation

@RehanSaeed How can you handle the .UseUrls() to wrap an if statment around it?

// Only add if development??

.UseUrls("https://localhost:5001")

@dotnetshadow Couldn't you do something like:

.UseUrls(hostingEnvironment.IsDevelopment() ? "http://*:8080" : "https://*:8080")

You can get hostingEnvironment like I showed but this should really be easier.

@RehanSaeed that's pretty cool, but what happens if you publish to an IIS environment?

@dotnetshadow Well, that would be a Production environment, so in my example above it would use the https URL.

@RehanSaeed thanks for that, I wasn't sure if IIS would still be able to use the .UseUrls() for a live site like foo.com

.UseUrls(hostingEnvironment.IsDevelopment() ? "http://*:8080" : "https://*:443")

IIS overwrites UseUrls.

@Tratcher ahh thank you I didn't know that. What about options.UseHttps() does that get overridden?

It will (though that may be broken right now in dev). @JunTaoLuo Do you have UseIISIntegration setting the new PreferHostingUrls?

@davidfowl has some ideas for another (nicer) workaround.

@Tratcher UseIISIntegration will set PreferHostingUrls after we address https://github.com/aspnet/IISIntegration/issues/352

@Tratcher ahh thank you didn't know there was PreferHostingUrls thing any documentation on that?

Is is possible to set UseHttps from Startup class?

Yes:

services.Configure<KestrelServerOptions>(options =>
 {
   options.UseHttps(...);
聽});

@RehanSaeed I was able to find a slightly shorter way before this gets implemented properly:

public static IHostingEnvironment hostingEnvironment;
public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration((hostingContext, config) => {
            hostingEnvironment = hostingContext.HostingEnvironment;
        })
            .UseKestrel(options => {
                if (hostingEnvironment.IsDevelopment()) {
                    options.Listen(IPAddress.Loopback, 443, listenOptions => {
                        listenOptions.UseHttps("certificate.pfx", "password");
                    });
                }
            })
        .Build();

Another way to do this:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
            .UseKestrel()
            .ConfigureServices((context, services) =>
            {
                services.Configure<KestrelServerOptions>(options =>
                {
                    if (context.HostingEnvironment.IsDevelopment())
                    {
                        options.Listen(IPAddress.Loopback, 443, listenOptions =>
                        {
                            listenOptions.UseHttps("certificate.pfx", "password");
                        });
                    }
                });
            })
        .Build();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tazer picture Tazer  路  4Comments

zpodlovics picture zpodlovics  路  6Comments

nmilosev picture nmilosev  路  9Comments

M-Curtis picture M-Curtis  路  3Comments

chtbof picture chtbof  路  3Comments