.NET Core | Kestrel with client certificate authentication

Eran Hadad
2 min readSep 5, 2020

--

Introduction

I’ll start this article with a very simple statement:
I intend to explain the subject in the simplest and quickest way possible.
If you are interested in exploring the subject further, please visit Microsoft Official site.

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1

Kestrel is a cross-platform web server for ASP.NET Core.

Kestrel is supported on all platforms and versions that .NET Core supports.

Kestrel in ASP.NET Core apps

Create new .net core web application empty project in visual studio.

How to Configure Https Defaults -

Open program.cs and use ConfigureKestrel —

.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(o =>
{
// certificate is an X509Certificate2
o.ServerCertificate = cert;
o.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
});

}).UseUrls($"https://*:{int.Parse(Configuration["Port"])}")
  • Load cert as embed resource and store the *.pfx password as encrypted (Salted password hashing in C#).
  • UseUrls allow you to specify the urls the web host will listen on.

How to Authentication with client certificate-

  • Open startup.cs and add services.AddAuthentication
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.AllowedCertificateTypes = CertificateTypes.All;
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
var validationService = context.HttpContext.RequestServices.GetService<ICertificateValdiaor>();
if(validationService.ValidateCertificate(context.ClientCertificate))
{
context.Success();
}
else
{
context.Fail("Invalid certifcate supplied");
}
return Task.CompletedTask;
}
};
});
  • ValidatonService is an implementation ICertificateValdiaor —
public bool ValidateCertificate(X509Certificate2 clientCertificate);

My implementation is compare between my certificate Thumbprint and client thumbprint , (you can add more validations if necessary).

public bool ValidateCertificate(X509Certificate2 clientCertificate)
{
try
{
bool result = false;
var cert = _resourcesManager.GetCertificateFromResource();
if (cert != null && clientCertificate.Thumbprint == cert.Thumbprint)
{
result = true;
}

return result;
}
catch (Exception ex)
{
_log.Error($"Failed to validate certificate {ex}");
throw ex;
}
}

Deploy (e.g. — Windows service) —

Go back to program.cs and modify Run() to

#if DEBUG
Run();
#else
RunAsService();
#endif

RunAsService is from another namespace-

Microsoft.AspNetCore.Hosting.WindowsServices

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response