ASP.NET Core Enforcing HTTPS

Home / ASP.NET Core Enforcing HTTPS

With OWIN and .NET 4.6.x, it was pretty straight forward to enable SSL (TLS), and redirect all requests to the HTTPS end-point with Visual Studio’s tooling (IIS Express). It’s not quite as straight forward to accomplish this in .NET Core.


.NET Core’s Middleware pipeline does allow one to intercept all requests. In that regard, it’s not terribly difficult to redirect anything that is not HTTPS to the HTTPS endpoint. In your Startup.cs’s Configure method, you could have something like this:

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var httpsUrl = "https://" + context.Request.Host + context.Request.Path;
        context.Response.Redirect(httpsUrl);
    }
});

That will actually work fine in production environments. In development environments, though, it falls flat. First, context.Request.Host will have the development port attached to it, and Visual Studio doesn’t expose what the SSL Port is directly afaik.

In .NET Core, we configure the SSL port in the launchSettings.json file located in the Properties folder. It looks like this:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:1234/",
      "sslPort": 44301
    }
  }
....
}

Fortunately, .NET Core makes it pretty easy to load the JSON configuration files and parse them. The default Startup.cs that you get when creating a new project already has a section within the Configure method that detects if we are running in debug mode. We can hook into this method and use the parse launchSettings.json to get the DEV debug port:

var sslPort = 0;
if (env.IsDevelopment())
{
	app.UseDeveloperExceptionPage();
	app.UseBrowserLink();

	var builder = new ConfigurationBuilder()
		.SetBasePath(env.ContentRootPath)
		.AddJsonFile(@"Properties/launchSettings.json", optional: false, reloadOnChange: true);
	var launchConfig = builder.Build();
	sslPort = launchConfig.GetValue<int>("iisSettings:iisExpress:sslPort");
}

After putting this code into place, our redirection code only needs to take advantage of the port (ignoring cases where the port is 0 or 443):

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var sslPortStr = sslPort == 0 || sslPort == 443 ? string.Empty : $":{sslPort}";
        var httpsUrl = $"https://{context.Request.Host.Host}{sslPortStr}{context.Request.Path}";
        context.Response.Redirect(httpsUrl);
    }
});

Leave a Reply