Configuring HTTPS in ASP.NET Core 2.1
Confession, ASP.NET Core 2.1 comes with HTTPS configured.... so in this post, we'll actually be showing you how to customize this configuration.
Join the DZone community and get the full member experience.
Join For FreeFinally, HTTPS has been put into ASP.NET Core. It was there before back in 1.1 but was kinda tricky to configure. It was available in 2.0 bit not configured by default. Now it is part of the default configuration and pretty much visible and present to the developers who will create a new ASP.NET Core 2.1 project.
So the title of this blog post is pretty much misleading because you don't need to configure HTTPS because it already is configured. So let's have a look how it is configured and how it can be customized. First, create a new ASP.NET Core 2.1 web application.
Did you already install the latest .NET Core SDK? If not, go to https://dot.net/ to download and install the latest version for your platform.
Open a console and CD to your favorite location to play around with new projects. It is C:\git\aspnet\ in my case.
mkdir HttpsSecureWeb && cd HttpSecureWeb
dotnet new mvc -n HttpSecureWeb -o HttpSecureWeb
dotnet run
These commands will create and run a new application called HttpSecureWeb. And you will see HTTPS the first time in the console output by running a newly created ASP.NET Core 2.1 application:
There are two different URLs where Kestrel is listening: https://localhost:5001 and http://localhost:5000.
If you go to the Configure method in the Startup.cs
there are some new middlewares used to prepare this web to use https.
In the Production and Staging environment mode there is this middleware:
app.UseHsts();
This enables HSTS (HTTP Strict Transport Protocol), which is an HTTP/2 feature to avoid man-in-the-middle attacks. It tells the browser to cache the certificate for the specific host-headers and for a specific time range. If the certificate changes before the time range ends, something is wrong with the page (More about HSTS).
The next new middleware redirects all requests without HTTPS to use the HTTPS version:
app.UseHttpsRedirection();
If you call http://localhost:5000, you get redirected to https://localhost:5001. This makes sense if you want to enforce HTTPS.
So, from the ASP.NET Core perspective, everything we need to do to run the web page using HTTPS is done. Unfortunately, the Certificate is missing. For production mode, you need to buy a valid trusted certificate and to install it in the Windows certificate store. For development mode, you are able to create a development certificate using Visual Studio 2017 or the .NET CLI. VS 2017 creates a certificate for you automatically.
Using the .NET CLI tool "dev-certs," you are able to manage your development certificates, like exporting them, cleaning all development certificates, trusting the current one, and so on. Just time the following command to get more detailed information:
dotnet dev-certs https --help
On my machine, I trusted the development certificate to not get the ugly error screen in the browser about an untrusted certificate and an unsecure connection every time I want to debug an ASP.NET Core application. This works quite well:
dotnet dev-cert https --trust
This command trusts the development certificate, by adding it to the certificate store or to the keychain on Mac.
On Windows, you should use the certificate store to register HTTPS certificated. This is the most secure way on Windows machines. But I also like the idea to store the password protected certificate directly in the web folder or somewhere on the web server. This makes it pretty easy to deploy the application to different platforms because Linux and Mac use different ways to store the certificated. Fortunately, there is a way in ASP.NET Core to create an HTTPS connection using a file certificate which is stored on the hard drive. ASP.NET Core is completely customizable. If you want to replace the default certification handling, feel free to do it.
To change the default handling, open the Program.cs
and take a quick look at the code, especially to the method CreateWebHostBuilder
:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
This method creates the default WebHostBuilder. This has a lot of stuff preconfigured, which is working great in the most scenarios. But it is possible to override all of the default settings here and to replace it with some custom configurations. We need to tell the Kestrel webserver which host and port it needs to listen on and we are able to configure the ListenOptions for specific ports. In this ListenOptions we can use HTTPS and pass in the certificate file and a password for that file:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("certificate.pfx", "topsecret");
});
})
.UseStartup<Startup>();
Usually, we would use the hardcoded values from a configuration file or environment variables, instead of hardcoding it.
Be sure the certificate is password protected using a long password or, even better, a pass-phrase. Be sure to not store the password or the pass-phrase into a configuration file. In development mode, you should use the user secrets to store such secret date and in production mode, the Azure Key Vault could be an option.
Conclusion
I hope this helps to get you a rough overview of the usage of HTTPS in ASP.NET Core. This is not really a deep dive but tries to explain what the new middlewares good are for and how to configure HTTPS for different platforms.
BTW: I just saw in the blog post about HTTPS improvements, about HSTS in ASP.NET Core, there is a way to store the HTTPS configuration in the launchSettings.json. This is an easy way to pass in environment variables on startup to the application. The samples also shows how to add the certificate password to this settings file. Please never ever do this! Because a file is easily shared to a source code repository or any other way, so the password inside is shared as well. Please use different mechanisms to set passwords in an application, like the already mentioned user secrets or the Azure Key Vault.
Published at DZone with permission of Juergen Gutsch, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments