J'ai eu le problème de passer une URL dans une bibliothèque qui appelait url.openConnection();
J'ai adapté la réponse de jon-daniel,
public class TrustHostUrlStreamHandler extends URLStreamHandler {
private static final Logger LOG = LoggerFactory.getLogger(TrustHostUrlStreamHandler.class);
@Override
protected URLConnection openConnection(final URL url) throws IOException {
final URLConnection urlConnection = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile()).openConnection();
// adapated from
// https://stackoverflow.com/questions/2893819/accept-servers-self-signed-ssl-certificate-in-java-client
if (urlConnection instanceof HttpsURLConnection) {
final HttpsURLConnection conHttps = (HttpsURLConnection) urlConnection;
try {
// Set up a Trust all manager
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
}
@Override
public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
}
} };
// Get a new SSL context
final SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
// Set our connection to use this SSL context, with the "Trust all" manager in place.
conHttps.setSSLSocketFactory(sc.getSocketFactory());
// Also force it to trust all hosts
final HostnameVerifier allHostsValid = new HostnameVerifier() {
@Override
public boolean verify(final String hostname, final SSLSession session) {
return true;
}
};
// and set the hostname verifier.
conHttps.setHostnameVerifier(allHostsValid);
} catch (final NoSuchAlgorithmException e) {
LOG.warn("Failed to override URLConnection.", e);
} catch (final KeyManagementException e) {
LOG.warn("Failed to override URLConnection.", e);
}
} else {
LOG.warn("Failed to override URLConnection. Incorrect type: {}", urlConnection.getClass().getName());
}
return urlConnection;
}
}
En utilisant cette classe, il est possible de créer une nouvelle URL avec :
trustedUrl = new URL(new URL(originalUrl), "", new TrustHostUrlStreamHandler());
trustedUrl.openConnection();
Cela présente l'avantage d'être localisé et de ne pas remplacer le système par défaut. URL.openConnection
.
2 votes
Voir Comment accepter un certificat auto-signé avec une HttpsURLConnection Java ? . Évidemment, il serait préférable que vous puissiez faire en sorte que le site utilise un certificat valide.
2 votes
Merci pour le lien, je ne l'avais pas vu en cherchant. Mais les deux solutions proposées impliquent un code spécial pour envoyer une requête et j'utilise un code existant (amazon ws client for java). Respectivement, c'est leur site que je connecte et je ne peux pas résoudre ses problèmes de certificat.
5 votes
@MatthewFlaschen - "Évidemment, ce serait mieux si vous pouviez faire en sorte que le site utilise un cert valide..." - Un certificat auto-signé est un certificat valide si le client lui fait confiance. Beaucoup pensent que le fait de confier la confiance au cartel CA/Navigateur est un défaut de sécurité.
4 votes
En rapport, voir Le code le plus dangereux du monde : la validation des certificats SSL dans les logiciels non-browsers . (Le lien est fourni puisque vous semblez recevoir ces réponses spammy qui désactivent la validation).