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.
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
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.
options.Events = new CertificateAuthenticationEvents
OnCertificateValidated = aMethod,
OnAuthenticationFailed = anotherMethod
It is not required to present
OnAuthenticationFailed at the same time. Check this doc for details.
Now, in the Nginx setting, some lines need to be added.
Check Certificate with Nginx
When need to check the client certificate by Nginx,
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
Not Check Certificate with Nginx
If we need Nginx to leave the certificate checking to core app, simply use the code
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. 😀