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

1

0

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."}
Hermelindahermeneutic answered 25/7, 2023 at 0:27 Comment(1)
Please provide a minimal reproducible example including app.Run code and settingsDoggett
L
1

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

Limitation answered 25/7, 2023 at 1:58 Comment(1)
ahhhh. That makes alot of sense. This change worked for me! Thanks heaps :)Hermelindahermeneutic

© 2022 - 2024 — McMap. All rights reserved.