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