Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forwarding Client Certifcate from Apache to Tomcat

I am trying to pass a x509 client certificate (I have a test cert installed on my browser) from the Apache web server (SSL) to the Tomcat application. The way I have it configured right now, the certificate is not being found (hence not forwarded) by the application's spring security.

DEBUG: [http-8080-1]  org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter - No client certificate found in request.

The Apache server ssl.conf file is configured like this (I have omitted the irrelevant parts):

LoadModule ssl_module modules/mod_ssl.so

Listen 443

AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

NameVirtualHost *:443

<VirtualHost *:443>

    ...

    SSLVerifyClient require
    SSLVerifyDepth 2

    ...

    # initialize the SSL headers to a blank value to avoid http header forgeries
    RequestHeader set SSL_CLIENT_CERT ""
    RequestHeader set SSL_CLIENT_VERIFY ""

    # add whatever SSL_* variables needed to pass to web application
    RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
    RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"

    RequestHeader add X-Forwarded-Scheme https

    ProxyPass /testcert http://127.0.0.1:8080/testcert
    ProxyPassReverse /testcert http://127.0.0.1:8080/testcert

</VirtualHost>

Is there any way to configure this in Apache where the entire certificate gets forwarded to the Tomcat server? I know I could use ajp but was trying to get it done without that method.

like image 237
James Avatar asked Feb 05 '13 21:02

James


1 Answers

If you're passing the certificate as a header, tomcat won't automatically be aware of it since the connection is just HTTP rather than HTTPS. Instead of getting the certifcate as a request attribute, you'll have to extract it from the header and parse it yourself.

You can override the getPreAuthenticationCredentials method in X509AuthenticationFilter. There's some code here which shows how to decode the certificate.

Bean Configuration

You remove the <x509 /> namespace element and replace it with the equivalent beans. There's an appendix in the reference manual which explains what beans an XML element creates. Your configuration should look like this:

<http entry-point-ref="http403">
    <custom-filter position="PRE_AUTH_FILTER" ref="x509Filter" />
</http>

<bean id="http403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />

<bean id="x509Filter" class="YourExtendedX509AuthenticaitonFilter" />
like image 83
Shaun the Sheep Avatar answered Oct 11 '22 23:10

Shaun the Sheep