So, instead configure Apache with a "SSLVerifyClient require" this is my ashamed solution: to configure a servlet filter (at first position in the chain) and, if there is no certificate in the request, just put one and go on.
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class X509CertificateFilter implements Filter { private static final Logger LOGGER = LoggerFactory.getLogger(X509CertificateFilter.class); private static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\r\n" + "MIIIdDCCB1ygAwIBAgIQIDbcJ3psq8FXD6IQBZA15DANBgkqhkiG9w0BAQsFADBN\r\n" + "(...)\r\n" + "740qIwTZlA4=\r\n" + "-----END CERTIFICATE-----"; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request.getAttribute("javax.servlet.request.X509Certificate") == null) { request.setAttribute("javax.servlet.request.X509Certificate", buildCertificates()); } chain.doFilter(request, response); } private static X509Certificate[] buildCertificates() { try { final InputStream is = new ByteArrayInputStream(CERTIFICATE.getBytes()); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) cf.generateCertificate(is); return new X509Certificate[] {cert}; } catch(Exception e) { LOGGER.error("Error injecting certificate", e); return null; } } }
You can also configure multiple certificates, for example in a map, and use a request parameter to pick one...
No hay comentarios:
Publicar un comentario