For standalone web server, there are generally three options for client certificate as long as SSL is enabled: Ignore, Accept, Require. Once we have a backend server with client certificate required then accessing it through an ARR server, a 502 issue would show up. This is because there is no way in the https protocol to have a proxy “delegate” the client certificate to the backend web-server although we can ensure both the communication between the client and ARR server as well as the communication between the ARR server and backend servers are using https.
Does it mean that with ARR configured the client certificate could never be used? Not exactly. Here are the steps to configure the servers and have the client certificate passed through to the backend application server.
1. First of all, please ensure the ARR server have the SSL enabled and the client certificate required:
For server and client certificate creation, you can refer to this blog with more details: http://blogs.msdn.com/b/asiatech/archive/2012/02/06/create-certificates-via-commands-for-testing-purpose.aspx
2. The backend application server should not have Accept/Require client certificates configured; otherwise, 502 will be returned from ARR server when trying to access the page;
3. Then the client certificate will be passed to the backend server as HTTP header with the default header configured as “X-ARR-ClientCert”;
4. And the certificate can be retrieved from backend server in this way:
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); string cert = Request.Headers["X-ARR-ClientCert"]; X509Certificate2 x509Cert2 = new X509Certificate2(encoding.GetBytes(cert));
5. Furthermore, you can change the header name to use your custom one or leave the header as blank so that no client certificate will be passed through.
a. If you are using server Farm(URL Rewrite Rules are usually configured at the Server level), then you can use the UI as below
Or the command similar as this:
c:\Windows\Systen32\inetsrv>appcmd set config -section:webFarms -[name='yourfarmname'].applicationRequestRouting.protocol.clientCertHeaderName:""
b. If you are using reverse proxy for application request routing(URL Rewrite Rules is usually configured with Default Web Site), then the header name can be configured here by opening the configuration editor with server name selected on IIS manager:
Alternatively, with command:
c:\Windows\Systen32\inetsrv>appcmd set config -section:system.webServer/proxy /clientCertHeaderName:”yourcustomHeadername” /commit:apphost
Wenbo Fu from GBSD DSI Team
Does this also work for Target Servers that are not within my server farm?
My ASP.NET Web API OWIN Middleware calls context.Get<X509Certificate2>("ssl.ClientCertificate") for getting a client certificate (if available). However, as soon as my API is behind a IIS Reverse Proxy AND the communication is over HTTPS (between RP and my API) the API call fails because context.Get(...) causes "An operation was attempted on a nonexistent network connection". In case I pass by the RP or the connection between RP and API is over HTTP it works...
You sir saved me many headaches and the remaining hair on my head; thank you!