Kestrelhttpserver: Https configuration issues with Kestrel in aspnetcore 2.0

Created on 22 May 2017  路  41Comments  路  Source: aspnet/KestrelHttpServer

I faced the issue https://github.com/dotnet/cli/issues/6516 and was advised to move to the docker image aspnetcore 2 rather than the dotnet.

dotnet --info

NET Command Line Tools (2.0.0-preview1-005977)

Product Information:
 Version:            2.0.0-preview1-005977
 Commit SHA-1 hash:  414cab8a0b

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.12
 OS Platform: Darwin
 RID:         osx.10.12-x64
 Base Path:   /usr/local/share/dotnet/sdk/2.0.0-preview1-005977/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.0-preview1-002111-00
  Build    : 1ff021936263d492539399688f46fd3827169983

startup.cs

 WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build().Run();

When I run my app locally, I set the ASPNETCORE_ENV to http://localhost:5000 using vscode tasks.
When I deploy (to Google App Engine) via Dockerfile, i set the following (notice http vs https):

EXPOSE 8080/tcp
ENV ASPNETCORE_URLS https://*:8080

This was good because I could control the port and http/https using environment variable only.
Now Kestrel returns:

System.InvalidOperationException: HTTPS endpoints can only be configured using KestrelServerOptions.Listen().

It seems I have to hardcode this value in Program.cs which I can't really do (flexibility is lost).

I deploy several services in docker containers that are ALL listening on port 8080 (Google App Engine requirement). App Engine provides the https certificate automatically so i do now own it (its probably just a reverse proxy by the way but it redirect to https).
But when I run them locally, I override the env var and specify some custom port 5000, 5001 so I can run them all at the same time...

How would you recommend I now handle this case using the aspnetcore 2.0 image?
The Kestrel ListenOptionsHttpsExtensions seem to require a certificate or a password which I do not have as it is managed by Google...

PS: If i use this code

.UseKestrel(options =>
                {
                    options.Listen(IPAddress.Any, 8080);
                }

and overrides using an environment variable on top, it won't:

Microsoft.AspNetCore.Server.Kestrel:Warning: Overriding address(es) http://*:5001. Binding to endpoints defined in UseKestrel() instead.
      Overriding address(es) http://*:5001. Binding to endpoints defined in UseKestrel() instead.

Most helpful comment

I ended up writing this code to load the configuration from file:

The changes to Program.cs:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseKestrel(SetHost)
        .UseStartup<Startup>()
        .Build();

where SetHost is the following method ("RafHost" is the configuration section):

private static void SetHost(Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions options)
{
    var configuration = (IConfiguration)options.ApplicationServices.GetService(typeof(IConfiguration));
    var host = configuration.GetSection("RafHost").Get<Host>();
    foreach (var endpointKvp in host.Endpoints)
    {
        var endpointName = endpointKvp.Key;
        var endpoint = endpointKvp.Value;
        if (!endpoint.IsEnabled)
        {
            continue;
        }

        var address = IPAddress.Parse(endpoint.Address);
        options.Listen(address, endpoint.Port, opt =>
        {
            if (endpoint.Certificate != null)
            {
                switch (endpoint.Certificate.Source)
                {
                    case "File":
                        opt.UseHttps(endpoint.Certificate.Path, endpoint.Certificate.Password);
                        break;
                    default:
                        throw new NotImplementedException($"The source {endpoint.Certificate.Source} is not yet implemented");
                }

                //opt.UseConnectionLogging();
            }
        });

        options.UseSystemd();   //?
    }
}

The configuration in appsettings.json is the following:

"RafHost": {
  "Endpoints": {
    "Http": {
      "IsEnabled":  true,
      "Address": "0.0.0.0",
      "Port": "5000"
    },

    "Https": {
      "IsEnabled": true,
      "Address": "0.0.0.0",
      "Port": "5443",
      "Certificate": {
        "Source": "File",
        "Path": "your-certificate.pfx",
        "Password": "(this should be a key to recover the password from a secure location)"
      }
    }
  }
}

and finally the configuration classes:

public class Host
{
    public Dictionary<string, Endpoint> Endpoints { get; set; }
}

public class Endpoint
{
    public bool IsEnabled { get; set; }
    public string Address { get; set; }
    public int Port { get; set; }
    public Certificate Certificate { get; set; }
}

public class Certificate
{
    public string Source { get; set; }
    public string Path { get; set; }
    public string Password { get; set; }
}

I hope this can help someone.

All 41 comments

Google can't provide a certificate automatically. If they are reverse proxying with ssl termination then kestrel will run in http

I assumed the same, i will revert everything back to http://localhost and will see if things are working properly

Does this help?

BTW can somebody confirm that using hosting.json that way is still the "correct" way of doing it?
I can update my answer on stackoverflow if it isn't.

Partially, the order of precedence is not clear though, UseUrls, KestrelOptions.Listen(), ASPNETCORE_ENV, and hosting.json. What order are options read from?

I assume this is 1.1? It's changed some for 2.0. @cesarbs ?

I did the update of some projects from 1.1 to 2.0 and I'm using hosting.json in 2.0
All I did was call the UseConfiguration method after CreateDefaultBuilder, like this

public static IWebHost BuildWebHost(string[] args) => 
    WebHost.CreateDefaultBuilder(args)
        .UseConfiguration(new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("hosting.json", optional: true)
            .Build()
        )
        .UseStartup<Startup>()
        .Build();

But I don't now if it is the correct way of doing it or if I should set the urls in another way.

@Jonathan34 After we changed the way Kestrel binds to addresses and ports - the new Listen() APIs -, you can only set up HTTPS endpoints via the new APIs. They are not supported in UseUrls() anymore, nor via environment variables.

If you want to be able to override your HTTP endpoints using the ASPNETCORE_URLS environment variable, you have to call PreferHostingUrls(true) on the web host builder e.g.:

var host = new WebHostBuilder()
    .UseKestrel(options =>
    {
        ...
    })
    .PreferHostingUrls(true)

If you don't want to set your HTTPS endpoints programmatically, you can use one of the ASP.NET Core metapackages. When using a metapackage you can configure Kestrel's endpoints (including HTTPS endpoints) using a configuration file. I recommend you look at the MetaPackages's repo SampleApp (https://github.com/aspnet/MetaPackages/tree/dev/samples/SampleApp) to learn how to set that up.

@cesarbs I see. I ended up listening to non https at the end as https seems to require we provide a certificate (which i don't have). That should be fine since Google handles this https connection from the outside.
You can close the ticket if you want

@Jonathan34 Indeed, not having the certificate would prevent you from setting HTTPS up in Kestrel.

I've just edited my previous post with a note on our metapackages, which enable you to use external configuration for HTTPS endpoints.

@cesarbs I can't find any documentation about the kestrel configuration changes and this is very frustrating. Could you please point everyone to a complete explanation about the configurations (by code and by config files) ?

Thank you

@raffaeler Kestrel configuration by config files still needs to be done manually at this point. https://github.com/aspnet/Announcements/issues/212 covers the new Kestrel binding/configuration APIs. If you aren't doing SSL termination in Kestrel, you can continue to call WebHostBuilder.UseUrls() like you do in Kestrel 1.x.

@halter73 Are you saying that everyone should craft his own config file, or that something will come in the 2.0 RTM?

@raffaeler Correct. I know it's not ideal. We started work on this feature, but we had to cut it due to some design questions (https://github.com/aspnet/Options/issues/195). We don't want to release an API that we would have to break in the next version. We're now targeting the release of the feature for 2.1.

In the meantime, if you want to see how we were considering implementing it, so you can do something similar, you can look at #1878. You don't need to have a separate conf file just for Kestrel. I would recommend adding a section to appsettings.json.

I ended up writing this code to load the configuration from file:

The changes to Program.cs:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseKestrel(SetHost)
        .UseStartup<Startup>()
        .Build();

where SetHost is the following method ("RafHost" is the configuration section):

private static void SetHost(Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions options)
{
    var configuration = (IConfiguration)options.ApplicationServices.GetService(typeof(IConfiguration));
    var host = configuration.GetSection("RafHost").Get<Host>();
    foreach (var endpointKvp in host.Endpoints)
    {
        var endpointName = endpointKvp.Key;
        var endpoint = endpointKvp.Value;
        if (!endpoint.IsEnabled)
        {
            continue;
        }

        var address = IPAddress.Parse(endpoint.Address);
        options.Listen(address, endpoint.Port, opt =>
        {
            if (endpoint.Certificate != null)
            {
                switch (endpoint.Certificate.Source)
                {
                    case "File":
                        opt.UseHttps(endpoint.Certificate.Path, endpoint.Certificate.Password);
                        break;
                    default:
                        throw new NotImplementedException($"The source {endpoint.Certificate.Source} is not yet implemented");
                }

                //opt.UseConnectionLogging();
            }
        });

        options.UseSystemd();   //?
    }
}

The configuration in appsettings.json is the following:

"RafHost": {
  "Endpoints": {
    "Http": {
      "IsEnabled":  true,
      "Address": "0.0.0.0",
      "Port": "5000"
    },

    "Https": {
      "IsEnabled": true,
      "Address": "0.0.0.0",
      "Port": "5443",
      "Certificate": {
        "Source": "File",
        "Path": "your-certificate.pfx",
        "Password": "(this should be a key to recover the password from a secure location)"
      }
    }
  }
}

and finally the configuration classes:

public class Host
{
    public Dictionary<string, Endpoint> Endpoints { get; set; }
}

public class Endpoint
{
    public bool IsEnabled { get; set; }
    public string Address { get; set; }
    public int Port { get; set; }
    public Certificate Certificate { get; set; }
}

public class Certificate
{
    public string Source { get; set; }
    public string Path { get; set; }
    public string Password { get; set; }
}

I hope this can help someone.

So what to do to make this work?
dotnet run --server.urls="https://*:44396;http://*:28187"

@xperiandri I believe you will have to parse the command line in Program.cs, Main method as i did for the configuration file.
My suggestion is to pass the configuration file name in the command line, and then load the urls (and certificate filename) from the configuration file. Also, remember not to store the password in clear text.

I hate to be rude about it, but this is absolutely ridiculous! The majority of people are already using UseUrls for it's simplicity and are not going through the hassle of manually binding their endpoints. Security should be in place by default, not some obscure convoluted implementation!

You don't have to parse anything. It's very simple:

```C#
var hostConfig = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();

var host = new WebHostBuilder()
.UseConfiguration(hostConfig)
.UseStartup();
.Build();
```

Now hosting will also read configuration from the command line.

BTW this is referring to @xperiandri's question above

I really don't get why UseHttps was moved out of KestrelOptions and into ListenOptions...it makes literally zero sense to do it that way

Can all interfaces at least be bound with 0.0.0.0?

@davidfowl you are confusing me now :)
What about the config files I asked previously in this thread? I had to write a custom support and @cesarbs stated 芦you can only set up HTTPS endpoints via the new APIs禄. I understand "no command line, no config files for https".
What about a good old documentation page with details on configuring http and https via

  • command line
  • config files
  • coded config
    ?

@davidfowl, doesn't work
C:\Users\袗薪写褉褨泄\Dev\Auth\src\Auth>dotnet run --server.urls="https://*:44396;http://*:28187"
args are empty

``` C#
public static class Program {
public static void Main(string[] args) {
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) {
    var host = new WebHostBuilder();

    if (args?.Any() ?? false) {
        var hostConfig = new ConfigurationBuilder()
            .AddCommandLine(args)
            .Build();
        host.UseConfiguration(hostConfig);
    }

    return host
           .UseContentRoot(Directory.GetCurrentDirectory())
           .ConfigureAppConfiguration((hostingContext, config) => {
               var env = hostingContext.HostingEnvironment;
               config
                   // Add configuration from the config.json file.
                   .AddJsonFile("config.json")
                   // Add configuration from an optional config.development.json, config.staging.json or
                   // config.production.json file, depending on the environment. These settings override the ones in the
                   // config.json file.
                   .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true);

               if (env.IsDevelopment()) {
                   var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                   if (appAssembly != null)
                       config.AddUserSecrets(appAssembly, optional: true);
               }

               // Add configuration specific to the Development, Staging or Production environments. This config can
               // be stored on the machine being deployed to or if you are using Azure, in the cloud. These settings
               // override the ones in all of the above config files.
               // Note: To set environment variables for debugging navigate to:
               // Project Properties -> Debug Tab -> Environment Variables
               // Note: To get environment variables for the machine use the following command in PowerShell:
               // [System.Environment]::GetEnvironmentVariable("[VARIABLE_NAME]", [System.EnvironmentVariableTarget]::Machine)
               // Note: To set environment variables for the machine use the following command in PowerShell:
               // [System.Environment]::SetEnvironmentVariable("[VARIABLE_NAME]", "[VARIABLE_VALUE]", [System.EnvironmentVariableTarget]::Machine)
               // Note: Environment variables use a colon separator e.g. You can override the site title by creating a
               // variable named AppSettings:SiteTitle. See http://docs.asp.net/en/latest/security/app-secrets.html
               config.AddEnvironmentVariables();

               if (args?.Any() ?? false)
                   config.AddCommandLine(args);

               // Push telemetry data through the Azure Application Insights pipeline faster in the development and
               // staging environments, allowing you to view results immediately.
               config.AddApplicationInsightsSettings(developerMode: !env.IsProduction());
           })
           .ConfigureLogging((hostingContext, logging) => {
               logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
               logging.AddConsole();
               logging.AddDebug();
           })
           .UseDefaultServiceProvider(
               (context, options)
               => options.ValidateScopes = context.HostingEnvironment.IsDevelopment())
           .UseKestrel(options => options.AddServerHeader = false)
           .PreferHostingUrls(true)
           .UseIISIntegration()
           .UseApplicationInsights()
           .UseAzureAppServices()
           .UseStartup<Startup>()
           .Build();
}

}
```

``C# C:\Users\袗薪写褉褨泄\Dev\Auth\src\Auth>dotnet run --server.urls="https://*:44396;http://*:28187" Using launch settings from C:\Users\袗薪写褉?泄\Dev\Auth\src\Auth\Properties\launchSettings.json... info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0] User profile is available. Using 'C:\Users\袗薪写褉?泄\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. info: Microsoft.EntityFrameworkCore.Infrastructure[100403] Entity Framework Core 2.1.0-preview1-26627 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=Auth info: Microsoft.EntityFrameworkCore.Update[300100] Saved 1 entities to in-memory store. info: Microsoft.EntityFrameworkCore.Infrastructure[100403] Entity Framework Core 2.1.0-preview1-26627 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=Auth info: Microsoft.EntityFrameworkCore.Update[300100] Saved 1 entities to in-memory store. info: Microsoft.EntityFrameworkCore.Update[300100] Saved 1 entities to in-memory store. info: Microsoft.EntityFrameworkCore.Update[300100] Saved 1 entities to in-memory store. info: Microsoft.EntityFrameworkCore.Update[300100] Saved 1 entities to in-memory store. crit: Microsoft.AspNetCore.Server.Kestrel[0] Unable to start Kestrel. System.InvalidOperationException: HTTPS endpoints can only be configured using KestrelServerOptions.Listen(). at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAddressAsync>d__7.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.<BindAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<StartAsync>d__221.MoveNext()

Unhandled Exception: System.InvalidOperationException: HTTPS endpoints can only be configured using KestrelServerOptions.Listen().
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.d__22`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at Auth.Program.Main(String[] args) in C:\Users\袗薪写褉?泄\Dev\Auth\src\AuthProgram.cs:line 12
``

This finally reads URLs but crashes too
``` C#
var hostConfig = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true);

#### hosting.json
``` JSON
{ "urls": "https://*:44396;http://*:28186" }

@raffaeler Sorry, I misread that HTTPS URL in the configured URLs.

HTTPS can't be configured this way. It requires server specific configuration.

@cesarbs do we have a reference to the config schema supported by kestrel for configuring HTTPS urls?

https://docs.microsoft.com/en-us/aspnet/core/security/https
So, this tutorial is no longer valid?

I use this configuration for development

  "Certificates": {
    "HTTPS": {
      "Source": "File",
      "Path": "..\\..\\DevelopmentCertificate.pfx",
      "Password": ""
    }
  },
  "Kestrel": {
    "Endpoints": {
      "LocalhostHttps": {
        "Address": "127.0.0.1",
        "Port": "44396",
        "Certificate": "HTTPS"
      }
    }
  }

@xperiandri according to what has been already said on this thread, the answer is no.
They removed the config-based configuration for https. The code I posted is the one I am currently using to workaround the removed feature.

@davidfowl There is no config schema supported by Kestrel for configuring HTTPS URLs. See https://github.com/aspnet/KestrelHttpServer/issues/1851#issuecomment-319211628

Did you named section RafHost not to conflict with Kestrel? Does it crash if Kestrel section present?

@raffaeler, I don't know why but it does not work.
I copied the code you mentioned to a separate assembly and updated my Program.cs this way

``` C#
public static IWebHost BuildWebHost(string[] args) {
var host = new WebHostBuilder();

//var hostConfig = new ConfigurationBuilder()
//    .SetBasePath(Directory.GetCurrentDirectory())
//    .AddJsonFile("hosting.json", optional: true);
//if (args?.Any() ?? false)
//    hostConfig.AddCommandLine(args);

//host.UseConfiguration(hostConfig.Build());

return host
       .UseContentRoot(Directory.GetCurrentDirectory())
       .ConfigureAppConfiguration((hostingContext, config) => {
           var env = hostingContext.HostingEnvironment;
           config
               .AddJsonFile("config.json")
               .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true);

           if (env.IsDevelopment()) {
               var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
               if (appAssembly != null)
                   config.AddUserSecrets(appAssembly, optional: true);
           }

           config.AddEnvironmentVariables();

           if (args?.Any() ?? false)
               config.AddCommandLine(args);

           config.AddApplicationInsightsSettings(developerMode: !env.IsProduction());
       })
       .ConfigureLogging((hostingContext, logging) => {
           logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
           logging.AddConsole();
           logging.AddDebug();
       })
       .UseDefaultServiceProvider(
           (context, options)
           => options.ValidateScopes = context.HostingEnvironment.IsDevelopment())
       .UseKestrel(KestrelConfiguration.SetHost)
       //.PreferHostingUrls(true)
       .UseIISIntegration()
       .UseApplicationInsights()
       .UseAzureAppServices()
       .UseStartup<Startup>()
       .Build();

}
```

I can't figure out what is wrong
C# System.InvalidOperationException occurred HResult=0x80131509 Message=HTTPS endpoints can only be configured using KestrelServerOptions.Listen(). Source=Microsoft.AspNetCore.Server.Kestrel.Core StackTrace: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAddressAsync>d__7.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.<BindAsync>d__2.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAsync>d__0.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<StartAsync>d__22`1.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Hosting.Internal.WebHost.<StartAsync>d__26.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Hosting.WebHostExtensions.<RunAsync>d__5.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Hosting.WebHostExtensions.<RunAsync>d__4.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host) at Aistant.Auth.Program.Main(String[] args) in C:\Users\袗薪写褉褨泄\Dev\Auth\src\Auth\Program.cs:line 16

@xperiandri Your bootstrap is very long. I suspect you are calling UseKestrel too late.
The SetHost method is just a way to configure Kestrel:
private static void SetHost(Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions options) { ... }

Could you please try with a brand new aspnetcore 2.0 project? I confirm that is working for me.

With regards to the RafHost section, it is not exactly the same of the Kestrel one. I tried to mime the configuration but I could not find a way that does not require a lot of code, therefore I simplified a bit the configuration by integrating the Certificates section into the endpoints.
In my project I do have both "RafHost" and "Kestrel" sections (appsettings.json) and they cannot collide since I use the first one while the second is ignored by UseKestrel.

HTH

@raffaeler
Ok so according to you the https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl documentation is also not really up to date in regard to Kestrell.

I was asking a question related to this issue on StackOverflow (https://stackoverflow.com/a/45854704/4636721) after watching Scot Hanselman (https://channel9.msdn.com/Events/Build/2017/B8048) but curiously even doing exactly what Scot and his friend were doing on stage it didn't work out for me...

So we basically have to force through the code the use of the appsettings.json (or the Developmentone). Makes me sad, as long as there is a way out, it's "fine" but do you know if there is any plan to change that in the next versions of ASP.NET Core? (or maybe just to the extend the behaviour with the DefaultBuilder just like what they are doing on Stage with Scot)?

@ehouarn-perret FYI I am just an MVP and not a MS employee nor a member of the dotnet team.

In the past preview releases the appsettings configuration worked even if with some glitches. Probably the demos by Scott&Scott stopped working on the bits released rightafter.
The only "official documentation" for these changes I am aware of, is this comment.

Maybe @davidfowl can clarify what are the current plans. I understand from this other comment there already plans and a candidate implementation for a possible future official implementation. My understanding is that there was not time but it will be done for the next release.

Meanwhile the implementation I posted is simple and very similar to the old one. It could be done to be exactly the same, but the configuration would have required much more code (therefore a waste of time for a temporary solution).

I just stumbled on this after having seen the HTTPS configuration in the appsettings.json in various videos about 2.0.

Just to clarify: There is no configuration file based way to set up HTTPS for Kestrel, right?

So the examples in videos, the documentation, and the meta packages sample is out of date for ASP.NET Core 2.0, right?

So the note in the comment above by @cesarbs about the functionality being available through the meta packages is also incorrect since there isn鈥檛 actually any logic in the meta packages that would make this configuration?

Note that I absolutely don鈥檛 mind having to set up the configuration by myself. It鈥檚 just that the current amount of misinformation that is spread all over everywhere is making this really confusing. So a final and clear clarification would really help.

@poke as of today it seems so, however, I am not working for Microsoft.

The problem is that we don't have any official news in that regard, except what has been already mentioned by halter73: aka https://github.com/aspnet/Options/issues/195

Another way to double confirm that is just to look at the source code, afaik there is nothing at the moment for Kestrel conf-wise.

I suspect that the documentation available and the video with Scot seem more related to ASP.NET Core 2.0 Preview version =/

As a matter of fact, https://docs.microsoft.com/en-us/aspnet/core/security/https clearly states that:

Note
This topic applies to ASP.NET Core 2.0 Preview 1

Can someone from Microsoft please address this? I just spend too much time following this tutorial today and it doesn't work on Mac. In fact, the default configuration builder doesn't seem to care about anything regarding Kestrel in appsettings.json. The docs need to be updated with the correct way of setting up Https for Kestrel in development.

@tura08 that doc has now been taken down. kestrel config file support was cut from 2.0.0. Config values need to be read manually in your initialization code.

@Tratcher that's a pity, it seemed like an elegant solution. Anyway, thanks for clearing that up. FWIW, to enable SSL in development, I am currently doing something like this in Program.cs:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
    .UseKestrel(options =>
        {
        options.Listen(IPAddress.Loopback, 44333, listenOptions =>
        {
            listenOptions.UseHttps("certificate.pfx", "password");
        });
    })
        .Build();

@raffaeler
regarding,
private static void SetHost(Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions ,

This is the best method that I have found till now,
Did you find solution for the args?

Thanks,

Guy

@guytwena can you please clarify what you want to do with the args?
If you mean the command line parameters, aspnet core expects a specific syntax that is used from the builder to select the appropriate configuration:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration#commandline-configuration-provider
What do you expect to do in SetHost with the args?

I've found this updated blog post https://blogs.msdn.microsoft.com/webdev/2017/11/29/configuring-https-in-asp-net-core-across-different-platforms/, in case some one hits here looking for Kestrel HTTPS configuration, bindings, certificates, etc.
And also a full sample: https://github.com/aspnet/samples/tree/master/samples/aspnetcore/security/KestrelHttps

Just in case some of you don鈥檛 have #1290 watched, @Tratcher pushed changes earlier that will make it easier to configure HTTPS and that will also allow us to configure HTTPS automatically using the previously promised configuration. So yay for that!

You can read the details on what will be possible starting with release 2.1 in his comment over there.

Was this page helpful?
0 / 5 - 0 ratings