I have to rewrite middleware in ASP.NET Core and this middleware makes use of some OWIN keys. Among them ssl.LoadClientCertAsync
and ssl.ClientCertificateErrors
. You can see similar middleware in this article. The essential part is this:
var task = (context.Environment["ssl.LoadClientCertAsync"] asFunc < Task > );
awaitTask.Run(task);
if (context.Environment.Keys.Contains("ssl.ClientCertificate"))
{
var cert = context.Environment["ssl.ClientCertificate"] asX509Certificate;
if (cert != null) context.Request.Environment.Add(SystemContants.OwinMannatechClientInfo, cert.Subject);
else
{
context.Response.StatusCode = 403;
return;
}
}
else
{
context.Response.StatusCode = 403;
return;
}
// Exception certError;
if (context.Environment.Keys.Contains("ssl.ClientCertificateErrors"))
{
//certError = context.Environment[OwinCertError] as Exception;
context.Response.StatusCode = 403;
return;
}
How can I convert it to use in ASP.NET Core? I know only that I can use context.Connection.ClientCertificate
for context.Environment["ssl.ClientCertificate"]
.
We can create the CertificateAuthenticationMiddleware to implement this feature.
using System.Security.Cryptography.X509Certificates;
namespace WebApplication2
{
public class CertificateAuthenticationMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<CertificateAuthenticationMiddleware> _logger;
public CertificateAuthenticationMiddleware(RequestDelegate next, ILogger<CertificateAuthenticationMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
var clientCert = await context.Connection.GetClientCertificateAsync();
if (clientCert != null)
{
if (IsCertificateValid(clientCert))
{
context.Items["ClientCertificate"] = clientCert.Subject;
}
else
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return;
}
}
else
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing client certificate.");
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return;
}
await _next(context);
}
private bool IsCertificateValid(X509Certificate2 certificate)
{
// add valid cert logic here
return certificate.NotBefore <= DateTime.UtcNow && certificate.NotAfter >= DateTime.UtcNow;
}
}
}