Open
Description
Background and motivation
It is currently possible to have a custom client certificate validation in Kestrel using
HttpsConnectionAdapterOptions.ClientCertificateValidation
However, it is currently impossible to have async validation without sync-over-async, since the signature of the callback is as below:
public Func<X509Certificate2, X509Chain?, SslPolicyErrors, bool>? ClientCertificateValidation { get; set; }
Example:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel(p =>
{
p.ConfigureHttpsDefaults(s =>
{
s.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
s.ClientCertificateValidation = (X509Certificate2 cert, X509Chain chain, SslPolicyErrors e) =>
{
Task<bool> someValidationTask = ...;
return someValidationTask.GetAwaiter().GetResult(); // sync-over-async
};
});
});
webBuilder.UseStartup<Startup>();
});
Intention is similar to dotnet/runtime#79441
API Proposal
namespace Microsoft.AspNetCore.Server.Kestrel.Https;
public Func<X509Certificate2, X509Chain?, SslPolicyErrors, ValueTask<bool>>? ClientCertificateValidation { get; set; }
API Usage
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel(p =>
{
p.ConfigureHttpsDefaults(s =>
{
s.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
s.ClientCertificateValidation = async (X509Certificate2 cert, X509Chain chain, SslPolicyErrors e) =>
{
Task<bool> someValidationTask = ...;
return await someValidationTask;
};
});
});
webBuilder.UseStartup<Startup>();
});
Alternative Designs
No response
Risks
Presence of two callbacks (sync and async) may confuse