Comment se connecter via HTTPS en utilisant Jsoup?
ça marche très bien sur HTTP, mais quand j'essaie D'utiliser une source HTTPS, ça lance l'exception suivante:
10-12 13:22:11.169: WARN/System.err(332): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
10-12 13:22:11.179: WARN/System.err(332): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:477)
10-12 13:22:11.179: WARN/System.err(332): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328)
10-12 13:22:11.179: WARN/System.err(332): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.setupSecureSocket(HttpConnection.java:185)
10-12 13:22:11.179: WARN/System.err(332): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:433)
10-12 13:22:11.189: WARN/System.err(332): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeConnection(HttpsURLConnectionImpl.java:378)
10-12 13:22:11.189: WARN/System.err(332): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:205)
10-12 13:22:11.189: WARN/System.err(332): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:152)
10-12 13:22:11.189: WARN/System.err(332): at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:377)
10-12 13:22:11.189: WARN/System.err(332): at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:364)
10-12 13:22:11.189: WARN/System.err(332): at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:143)
voici le code correspondant:
try {
doc = Jsoup.connect("https url here").get();
} catch (IOException e) {
Log.e("sys","coudnt get the html");
e.printStackTrace();
}
8 réponses
si vous voulez le faire de la bonne façon, et/ou vous devez traiter avec un seul site, alors vous avez essentiellement besoin de saisir le certificat SSL du site en question et de l'importer dans votre boutique Java key. Il en résultera un fichier JKS que vous définirez à votre tour comme étant SSL trust store avant d'utiliser Jsoup (ou java.net.URLConnection
).
vous pouvez prendre le certificat de votre magasin webbrowser. Supposons que vous utilisez Firefox.
- Go sur le site en question en utilisant Firefox, qui est dans votre cas https://web2.uconn.edu/driver/old/timepoints.php?stopid=10
- à gauche dans la barre d'adresse vous verrez "uconn.edu "en bleu (Ceci indique un certificat SSL valide)
- Cliquez dessus pour plus de détails, puis cliquez sur le Plus d'informations bouton.
- dans le dialogue de sécurité qui apparaît, cliquez sur la vue Certificat bouton.
- dans le panneau de certificat qui apparaît, allez à l'onglet détails .
- cliquez sur l'élément le plus profond de la hiérarchie des certificats, qui est dans ce cas "web2.uconn.edu" et enfin cliquez sur le bouton exporter .
Maintenant vous avez un fichier web2.uconn.edu.crt
.
Ensuite, ouvrez la commande prompt et importez-la dans le Java key store à l'aide de la commande keytool
(elle fait partie du JRE):
keytool -import -v -file /path/to/web2.uconn.edu.crt -keystore /path/to/web2.uconn.edu.jks -storepass drowssap
le -file
doit pointer vers l'emplacement du fichier .crt
que vous venez de télécharger. Le -keystore
doit pointer vers L'emplacement du fichier .jks
généré (que vous voulez à votre tour Définir comme le SSL trust store). Le -storepass
est nécessaire, vous pouvez simplement entrer n'importe quel mot de passe que vous voulez aussi longtemps qu'il est au moins 6 caractères.
Maintenant, vous avez un fichier web2.uconn.edu.jks
. Vous pouvez enfin le Définir comme SSL trust store avant de vous connecter comme suit:
System.setProperty("javax.net.ssl.trustStore", "/path/to/web2.uconn.edu.jks");
Document document = Jsoup.connect("https://web2.uconn.edu/driver/old/timepoints.php?stopid=10").get();
// ...
comme une alternative complètement différente, en particulier lorsque vous avez besoin de traiter avec plusieurs sites (i.e. vous créez un World wide Web crawler), alors vous pouvez également donner des instructions à Jsoup (essentiellement, java.net.URLConnection
) de faire confiance aveuglément à tous les certificats SSL. Voir aussi la section "Gestion des sites HTTPS non sécurisés ou mal configurés" en bas de page de cette réponse: en utilisant java.net.URLConnection to fire and handle HTTP requests
j'ai trébuché sur les réponses ici et dans la question liée dans ma recherche et je veux ajouter deux éléments d'information, car la réponse acceptée ne correspond pas à mon scénario tout à fait similaire, mais il y a une solution supplémentaire qui correspond même dans ce cas (cert et hostname ne correspondent pas aux systèmes de test).
- il y a une requête github pour ajouter une telle fonctionnalité. Alors peut-être que bientôt le problème sera résolu: https://github.com/jhy/jsoup/pull/343 edit: Github demande a été résolu et la méthode pour désactiver la validation du certificat est: validateTLSCertificates(boolean valider)
- basé sur http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections / j'ai trouvé une solution qui semble fonctionner (au moins dans mon scénario où jsoup 1.7.3 est appelé dans le cadre d'une tâche maven). J'ai enveloppé dans une méthode
disableSSLCertCheck()
que j'appelle avant la première Jsoup.connecter.)(
avant d'utiliser cette méthode , vous devriez être vraiment sûr que vous comprenez ce que vous faites là - bas-ne pas vérifier les certificats SSL est une chose vraiment stupide. Utilisez toujours les certificats SSL corrects pour vos serveurs qui sont signés par une AC généralement acceptée. Si vous ne pouvez pas vous permettre un CA généralement accepté utiliser des certificats SSL corrects néanmoins avec @BalusC accepté réponse ci-dessus. Si vous ne pouvez pas configurer correctement SSL certificats (CE qui ne devrait jamais être le cas dans les environnements de production) la méthode suivante pourrait fonctionner:
private void disableSSLCertCheck() throws NoSuchAlgorithmException, KeyManagementException {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
dans mon cas, tout ce que je devais faire était d'ajouter le .validateTLSCertificates(false) dans ma connexion
Document doc = Jsoup.connect(httpsURLAsString)
.timeout(60000).validateTLSCertificates(false).get();
j'ai également eu à augmenter le délai d'attente, mais je pense que ce n'est pas pertinent
j'ai eu le MÊME PROBLÈME MAIS j'ai pris la route paresseuse - dites à votre application d'ignorer le cert et continuer de toute façon.
j'ai le code d'ici: comment utiliser une URL locale HTTPS en java?
vous devrez importer ces classes pour que cela fonctionne:
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
il suffit d'exécuter cette méthode quelque part avant d'essayer de faire la connexion et voilà, il fait confiance au cert quoi qu'il arrive. Bien sûr, cela n'est pas une aide si vous voulez réellement s'assurer que le cert est réel, mais bon pour la surveillance de vos propres sites Web internes, etc.
Je ne suis pas un expert dans ce domaine, mais j'ai rencontré une exception similaire en essayant de se connecter à un site web sur HTTPS en utilisant java.net APIs. Le navigateur fait beaucoup de travail pour vous en ce qui concerne les certificats SSL lorsque vous visitez un site en utilisant HTTPS. Cependant, lorsque vous vous connectez manuellement à des sites (en utilisant des requêtes HTTP manuellement), tout ce travail doit encore être fait. Maintenant je ne sais pas ce que tout ce travail est exactement, mais il a à voir avec le téléchargement des certificats et de les mettre où Java peut les trouver. Voici un lien qui nous l'espérons vous pointer dans la bonne direction.
http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services
je faisais face au même problème avec Jsoup, Je n'ai pas pu me connecter et obtenir le document pour les urls https mais quand j'ai changé ma version JDK de 1.7 à 1.8, le problème a été résolu.
Ça peut vous aider :)
j'ai eu ce problème seulement dans l'environnement dev. La solution pour le résoudre était juste d'ajouter quelques drapeaux pour ignorer SSL à VM:
-Ddeployment.security.TLSv1.1=false
-Ddeployment.security.TLSv1.2=false
essayez de suivre (mettez-le juste avant Jsoup.connect("https://example.com")
:
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});