Как отключить проверку сертификата в клиенте JAX-WS?
Как отключить проверку сертификата в клиенте JAX-WS с помощью javax.xml.ws.Service
?
Я попытался создать доверяющий TrustManager в SSLSocketFactory и попытался связать его с BindingProvider
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
Map<String, Object> ctxt = ((BindingProvider) wsport ).getRequestContext();
ctxt.put(JAXWSProperties.SSL_SOCKET_FACTORY, sc.getSocketFactory());
но я все еще получаю Exception: unable to find valid certification path to requested target
Но он работает, когда я просто использую
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Или есть способ сделать javax.xml.ws.Service
использовать созданный мной HttpsURLConnection
?
Ответы
Ответ 1
Я нашел решение здесь:
http://schrepfler.blogspot.com.br/2009/06/relaxing-ssl-validation-for-jaxws.html
Я использую это решение, вызывающее два статических метода в статическом блоке в основном классе, например:
static {
SSLUtilities.trustAllHostnames();
SSLUtilities.trustAllHttpsCertificates();
}
Надеюсь, что это поможет
Ответ 2
Правду можно найти в блоге Erik Wramner здесь http://erikwramner.wordpress.com/2013/03/27/trust-self-signed-ssl-certificates-and-skip-host-name-verification-with-jax-ws
Обратите внимание также на комментарий Николая Смирнова. Я использую jdk 7 и glassfish 3.1.2. В этой среде предлагаемое решение работает идеально, если сервер имеет дело с самоподписанным сертификатом.
Я включаю полное решение для последующей ссылки, включая решение, когда используется Apache CXF:
// import com.sun.xml.ws.developer.JAXWSProperties;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.BindingProvider;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
/**
*
* Usage examples (BindingProvider port):
* NaiveSSLHelper.makeWebServiceClientTrustEveryone(port); // GlassFish
* NaiveSSLHelper.makeCxfWebServiceClientTrustEveryone(port); // TomEE
*
* Based on Erik Wramner example frome here:
* http://erikwramner.wordpress.com/2013/03/27/trust-self-signed-ssl-certificates-and-skip-host-name-verification-with-jax-ws/
*
* I have extended the functionality when Apache CXF is used.
*/
public class NaiveSSLHelper {
private static final String JAXWS_HOSTNAME_VERIFIER = "com.sun.xml.ws.transport.https.client.hostname.verifier"; // JAXWSProperties.HOSTNAME_VERIFIER;
private static final String JAXWS_SSL_SOCKET_FACTORY = "com.sun.xml.ws.transport.https.client.SSLSocketFactory"; // JAXWSProperties.SSL_SOCKET_FACTORY;
// In Glassfish (Metro) environment you can use this function (Erik Wramner solution)
public static void makeWebServiceClientTrustEveryone(Object webServicePort) {
if (webServicePort instanceof BindingProvider) {
BindingProvider bp = (BindingProvider) webServicePort;
Map requestContext = bp.getRequestContext();
requestContext.put(JAXWS_SSL_SOCKET_FACTORY, getTrustingSSLSocketFactory());
requestContext.put(JAXWS_HOSTNAME_VERIFIER, new NaiveHostnameVerifier());
} else {
throw new IllegalArgumentException(
"Web service port "
+ webServicePort.getClass().getName()
+ " does not implement "
+ BindingProvider.class.getName());
}
}
// In TomEE (Apache CXF) environment you can use this function (my solution)
public static void makeCxfWebServiceClientTrustEveryone(Object port) {
TrustManager[] trustManagers = new TrustManager[]{
new NaiveTrustManager()
};
Client c = ClientProxy.getClient(port);
HTTPConduit httpConduit = (HTTPConduit) c.getConduit();
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setKeyManagers(new KeyManager[0]);
tlsParams.setTrustManagers(trustManagers);
tlsParams.setDisableCNCheck(true);
httpConduit.setTlsClientParameters(tlsParams);
}
public static SSLSocketFactory getTrustingSSLSocketFactory() {
return SSLSocketFactoryHolder.INSTANCE;
}
private static SSLSocketFactory createSSLSocketFactory() {
TrustManager[] trustManagers = new TrustManager[]{
new NaiveTrustManager()
};
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(new KeyManager[0], trustManagers, new SecureRandom());
return sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
return null;
}
}
private static interface SSLSocketFactoryHolder {
public static final SSLSocketFactory INSTANCE = createSSLSocketFactory();
}
private static class NaiveHostnameVerifier implements
HostnameVerifier {
@Override
public boolean verify(String hostName,
SSLSession session) {
return true;
}
}
private static class NaiveTrustManager implements
X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws java.security.cert.CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}
}