Search code examples
c#asp.net-core.net-6.0kestrel-http-serverkestrel

c# app.Run() is failing because UseKestrel() is not waiting for the Defaults to be configured


I have tried the following two functions to configure Kestrel:

public static void UseKestralConfigurations(this WebApplicationBuilder builder)
{
    _ = builder.Services.Configure<KestrelServerOptions>(options =>
    {
        options.ConfigureHttpsDefaults(options =>
        {
            options.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
            options.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
            //options.ClientCertificate
            options.ClientCertificateValidation = (cert, chain, policyErrors) =>
                // Certificate validation logic here
                // Return true if the certificate is valid or false if it is invalid
                true;
            options.CheckCertificateRevocation = false;
            options.ServerCertificate = LoadCertificate();
        });
    });
}

And the more modern UseKestrel():

public static void UseKestrel(this WebApplicationBuilder builder)
{
    builder.WebHost.UseKestrel(options =>
    {
        options.ConfigureHttpsDefaults(defaults =>
        {
            defaults.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
            defaults.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
            // defaults.ClientCertificate
            defaults.ClientCertificateValidation = (cert, chain, policyErrors) =>
                // Certificate validation logic here
                // Return true if the certificate is valid or false if it is invalid
                true;
            defaults.CheckCertificateRevocation = false;
            defaults.ServerCertificate = LoadCertificate();
        });
    });
}

But neither works. When I am debugging, and first step into this function, it does not even seem to run Configure(), or UseKestrel() at all. This makes some sense since they run when the builder is built.

But when the builder is built and the app is created with var app = builder.Build(), the inner function: options.ConfigureHttpsDefaults() is never run. It just completely skips over this function. And never configures the ServerCertificate. So when the app is run (app.Run()), it immediately throws the following error:

{"The endpoint HttpsInlineCertFile is missing the required 'Url' parameter."}

Solution

  • You may try as below:

    var builder = WebApplication.CreateBuilder(args);
    builder.WebHost.ConfigureKestrel(op =>
    {
        op.ConfigureHttpsDefaults(defaults =>
        {
            defaults.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
            defaults.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
            // defaults.ClientCertificate
            defaults.ClientCertificateValidation = (cert, chain, policyErrors) =>
                // Certificate validation logic here
                // Return true if the certificate is valid or false if it is invalid
                true;
            defaults.CheckCertificateRevocation = false;
            ....
            
        });
    });
    

    It works on myside:

    enter image description here

    Accroding to this document:

    ASP.NET Core project templates use Kestrel by default when not hosted with IIS. In the following template-generated Program.cs, the WebApplication.CreateBuilder method calls UseKestrel internally:

    So you don't have to call UseKestrel again ,just configure the options

    builder.Services.Configure<SomeOptions>
    

    configures the options registed in the default container:IServiceCollection