When dotnet core app is deployed in Linux with Kestrel, nginx works in front as a proxy. Usually, Nginx will handle all https related issue and forward a plain http request to core app. Some app may require clients to use certificate for authentication. In this case, client certificate need to be transferred to core app.
Core App
First, the core app need to be prepared to receive and check the client certificate.
public class StartUp
{
...
public void ConfigureServices(IServiceCollection services)
{
...
//Add code here
services.AddCertificateForwarding(options => "X-ARR-ClientCert");
//PointA - for later reference
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
//Add code here
app.UseAuthorization();
app.UseCertificateForwarding();
...
}
}
Note: UseHttpsRedirection()
cannot be used because the core app is set to use http only. UseCertificateForwarding()
may expose a security issue, you could set a switch to open it only when required. The header name X-ARR-ClientCert
can be changed as your wish.
By default, core app will validate client certificate with local trusted CA. For additional tuning, add this code to the PointA
position above.
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = aMethod,
OnAuthenticationFailed = anotherMethod
};
It is not required to present OnCertificateValidated
and OnAuthenticationFailed
at the same time. Check this doc for details.
Nginx
Now, in the Nginx setting, some lines need to be added.
Check Certificate with Nginx
When need to check the client certificate by Nginx,
ssl_client_certificate file;
ssl_verify_client on;
is required. The file
should contain trusted CA certificates in PEM format. When using multiple CA certificates, write all of them into the same file. When client certificate is not forcible, change on
to optional
.
Not Check Certificate with Nginx
If we need Nginx to leave the certificate checking to core app, simply use the code
ssl_verify_client optional_no_ca;
in site file. This will let Nginx transfer the client certificate to proxy without touch.
Pass to Proxy
After processing one of those above, the client certificate is ready to be passed into the proxy app — core app. This code below will do that.
proxy_set_header X-ARR-ClientCert $ssl_client_escaped_cert;
If you changed the name X-ARR-ClientCert
above, use the same value here. This code can be placed into location block too.
Now you can enjoy your dirty job by checking everything about client certificate in your core app. 😀