Certificate-based Authentication is the use of a Digital Certificate to identify a client request before granting it the access to a resource, network, application, etc. Certificate Authentication provides added security to web applications. You can easily implement it in ASP.NET Core 3.0. Let us understand how to do it.
In your ASP.NET Core app, first add the package called Microsoft.AspNetCore.Authentication.Certificate from NuGet.
Check the below code which does the exact thing:
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddAuthentication( CertificateAuthenticationDefaults.AuthenticationScheme) .AddCertificate(options => { options.Events = new CertificateAuthenticationEvents { OnCertificateValidated = context => { var validationService = context.HttpContext.RequestServices.GetService<MyCertificateValidationService>(); if (validationService.ValidateCertificate(context.ClientCertificate)) { context.Success(); } else { context.Fail("invalid cert"); } return Task.CompletedTask; }, OnAuthenticationFailed = context => { context.Fail("invalid cert"); return Task.CompletedTask; } }; }); }
Note that inside the OnAuthenticationFailed event you show ‘invalid cert’ message.
I have also specified MyCertificateValidationService class where the certificate will be validated. It’s full code is given below:
public class MyCertificateValidationService { public bool ValidateCertificate(X509Certificate2 clientCertificate) { var cert = new X509Certificate2(Path.Combine("localhost_root_l1.pfx"), "1234"); if (clientCertificate.Thumbprint == cert.Thumbprint) { return true; } return false; } }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseCertificateForwarding(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .ConfigureKestrel(options => { options.ConfigureHttpsDefaults(opt => opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate); }) .Build();
Download full source codes:
Download
Thanks much for your wonderful tutorial for the client certificate. I am having a problem connecting to the service from my console client.
var cert = new X509Certificate2(@”c:\…\root_localhost.pfx”, “1234”);
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(cert);
var client = new HttpClient(handler);
var request = new HttpRequestMessage()
{
RequestUri = new Uri(“https://localhost”),
Method = HttpMethod.Get,
};
var response = await client.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
//I am getting 403 always
}
I checked “Require SSL” on IIS SSL Ssettings and checked “Client Certirficate” to be “Required”.
I can’t figure out how to make it work.
Any help and advice are appreciated.
Thank again.
Yong
Most probably the reason can be the Certificate is not allowed by the browser. You should try regenerating a new Root and client certificates from the Powershell command. Hope it helps you.
Regards,
Yogi
Thanks for the post. I implanted my certificate authentication based on your post. When I run my application in my windows 10 machine everything works correctly. However when I use docker, call my url (for example https://localhost:5001/api) I am having e err_connection_closed issue. Any suggestion please ? Thank you
Hello. thank you for the post. I used the tutorial to add certifccate authentication in my app, it owrks perfectly on Windows. However when I execute the app on Ubuntu, I am always having an “ERR_CONNECTION_CLOSED”. I generated a certificate using openssl on my ubuntu machine but I am still having the same issue.
PS: if I comment the lines
“””
.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(opt =>
opt.ClientCertificateMode =
ClientCertificateMode.RequireCertificate);
})
“””
I am able to get a response, however the request has no certificate.
Any idea ? Thank you
I run sample code and get Access to localhost was denied You don’t have authorization to view this page.
HTTP ERROR 403