Apache 2.4 proxy server gets Client Authentication but doesn’t pass it to tomcat

apache-2.4authenticationproxy-authenticationreverse-proxy

I have previously had Apache 2.2.17 running as a reverse proxy which would request client authentication (using SSLVerifyClient) and would pass on that authentication to the jetty/tomcat application servlet engine. Then my Java application would read that information (x509Certificate) from the request.

When upgrading to new servers we decided to migrate to the latest version of Apache, but this process no longer seems to work. Apache still requests the client authentication, but it doesn't seem to pass that along to Tomcat.

Here are the relevant bits of the working (v2.2.17) httpd.conf file:

<VirtualHost _default_:443>

    ServerName xxxxxxxx
    SSLEngine On

    SSLCertificateFile conf/ssl-prod/xxxxxxxx.crt
    SSLCertificateKeyFile conf/ssl-prod/xxxxxxxx.key
    SSLCACertificatePath conf/ssl.certs/

    <Location />
        ProxyPass http://xxxxxxxx:8009/
        ProxyPassReverse http://xxxxxxxx:8009/

        Order deny,allow
        Allow from all
    </Location>

    <Location /login/>
        SSLVerifyClient optional
        SSLVerifyDepth 10

        ProxyPass http://xxxxxxxx:8009/
        ProxyPassReverse http://xxxxxxxx:8009/

        Order deny,allow
        Allow from all
    </Location>

</VirtualHost>

So, it is just a standard SSL proxy until the user goes to a page in the "login" folder at which point apache asks for client authentication.

I have tried setting a few other variables to see if that would cause it to work
ProxyAddHeaders On
ProxyPreserverHost On (and Off)
but had no success.

We also had the same issue when moving to the lastest version of the 2.2.23 branch, but when we copied the older version we were using to the new server it worked fine. The only other difference is that we're moving from a 32-bit to a 64-bit server (both Windows using ApacheLounge executables).

Any ideas?

Best Answer

You don't have any mechanism in place to pass the information about the authenticated client to the Tomcat server.

AJP is the protocol that's used on port 8009 by default, not HTTP - and it has mechanisms built in for passing client certificate data (as long as SSLOptions +ExportCertData is in place in Apache). Are you sure you're not intending to use that?

If not, you'll need to implement something to handle this, in Apache as well as in your Tomcat application. Probably an HTTP header with information about the client certificate.