Search code examples
.netasp.net-core.net-6.0webapiclient-certificates

Certificate Based Authentication in ASP.Net core Web API Not Working


I am trying to implement Certificate based Authentication in .NET 6 WEB API, but I am getting below error while calling the API's end points. I am adding the certificate in HttpClientHandler also

Please let me know the solution for this error.

Error: enter image description here

My Project Code below,

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.ConfigureKestrel(options =>
                {
                    options.ConfigureHttpsDefaults(o =>
                    {
                        o.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
                    });
                });
            });
}

Startup.cs

public class Startup
{
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<CertificateValidationService>();
            services.ConfigureAuthetication();
            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "CertificateAuth", Version = "v1" });
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.ConfigureExceptionHandler(env);
            if (env.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CertificateAuth v1"));
            }

            app.UseHttpsRedirection();
            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();
         
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
}

CertificateValidationService.cs

public class CertificateValidationService
    {
        public bool ValidateCertificate(X509Certificate2 clientCertificate)
        {          
            
            var cert = new X509Certificate2(Path.Combine("dev_cert.pfx"), "1234");

            if (clientCertificate.Thumbprint == cert.Thumbprint)
            {
                return true;
            }
    
            return false;
        }
    }

WeatherForecastController.cs

[ApiController]
[Route("[controller]")]
[Authorize]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

Client App for testing the API

using System.Security.Cryptography.X509Certificates;

var cert = new X509Certificate2(@"dev_cert.pfx", "1234");
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(cert);
var client = new HttpClient(handler);

var request = new HttpRequestMessage()
{
    RequestUri = new Uri("https://localhost:7251/weatherforecast"),
    Method = HttpMethod.Get,
};
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
    var responseContent = await response.Content.ReadAsStringAsync();
    Console.WriteLine(responseContent);
}


Solution

  • We have to import the CA certificate to current machine

    • Click Start and type “Manage Computer Certificates”. You will see the below,
    • Select “Trusted Root Certification Authorities- Certificates – All Tasks- Import” and add the CA certificate to it. You will be asked to provide the password. Here provide the password used to generate the CA certificate file.