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();
}
}
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?
@dotnetshadow it's new for 2.0:
https://github.com/aspnet/Hosting/commit/4cdc970055ef2ad77887109c4acde89278e0ce18
This covers https://github.com/aspnet/KestrelHttpServer/issues/1713 too.
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();
Most helpful comment
Another way to do this: