2011-10-12 13 views
15

यह HTTP पर ठीक काम कर रहा है, लेकिन जब मैं कोशिश करते हैं और एक HTTPS स्रोत का उपयोग यह निम्न अपवाद फेंकता है:Jsoup का उपयोग कर HTTPS के माध्यम से कैसे कनेक्ट करें?

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) 

यहाँ प्रासंगिक कोड है:

try { 
    doc = Jsoup.connect("https url here").get(); 
} catch (IOException e) { 
    Log.e("sys","coudnt get the html"); 
    e.printStackTrace(); 
} 

उत्तर

44

आप इसे सही तरीके से करना चाहते हैं, और/या आप केवल एक साइट के साथ सौदा करने की जरूरत है, तो आप मूल रूप से प्रश्न में वेबसाइट के SSL प्रमाणपत्र हड़पने और इसे आयात करने की आवश्यकता आपके जावा कुंजी स्टोर। इसके परिणामस्वरूप एक जेकेएस फ़ाइल होगी जिसे आप जेएसओपी (या java.net.URLConnection) का उपयोग करने से पहले एसएसएल ट्रस्ट स्टोर के रूप में सेट करते हैं।

आप अपने वेबब्रोसर स्टोर से प्रमाण पत्र ले सकते हैं। आइए मान लें कि आप फ़ायरफ़ॉक्स का उपयोग कर रहे हैं।

  1. विचाराधीन वेबसाइट Firefox का उपयोग कर, जो अपने मामले में है https://web2.uconn.edu/driver/old/timepoints.php?stopid=10
  2. पता पट्टी में वाम आप "uconn.edu" नीले रंग में दिखाई देगा (यह एक वैध SSL प्रमाणपत्र को इंगित करता है) पर जाएं
  3. विवरण के लिए इसके लिए क्लिक करें और फिर पर अधिक जानकारी बटन पर क्लिक करें।
  4. दिखाई देने वाली सुरक्षा वार्ता में, पर क्लिक करें प्रमाणपत्र बटन देखें।
  5. प्रमाण पत्र पैनल जो प्रकट होती है, विवरण टैब पर जाएं।
  6. प्रमाण पत्र पदानुक्रम की गहरी वस्तु पर क्लिक करें, जो इस मामले में "web2.uconn.edu" है और अंत में निर्यात बटन पर क्लिक करें।

अब आपके पास web2.uconn.edu.crt फ़ाइल है।

इसके बाद, कमांड प्रॉम्प्ट खोलें और जावा कुंजी keytool आदेश का उपयोग कर दुकान में आयात (यह JRE का हिस्सा है):

keytool -import -v -file /path/to/web2.uconn.edu.crt -keystore /path/to/web2.uconn.edu.jks -storepass drowssap 

-file.crt फ़ाइल का स्थान को इंगित करना चाहिए कि कौन सा बस डाउनलोड किया गया। -keystore उत्पन्न .jks फ़ाइल (जो आप बदले में एसएसएल विश्वास दुकान के रूप में सेट करना चाहते हैं) के स्थान को इंगित करना चाहिए। -storepass आवश्यक है, आप केवल तब तक जो भी पासवर्ड चाहते हैं उसे दर्ज कर सकते हैं जब तक कि कम से कम 6 वर्ण हों।

अब, आप एक web2.uconn.edu.jks फ़ाइल है।आप अंत में जोड़ने से पहले एसएसएल विश्वास की दुकान के रूप में सेट कर सकते हैं इस प्रकार है:

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(); 
// ... 

एक पूरी तरह से अलग विकल्प है, खासकर जब आप (कई साइटों से निपटने के लिए की जरूरत के रूप में यानी आप एक वर्ल्ड वाइड वेब क्रॉलर बना रहे हैं), तो आप जेएसओपी (मूल रूप से, java.net.URLConnection) को सभी एसएसएल प्रमाण पत्रों पर भरोसा करने के लिए भी निर्देश दे सकते हैं। इस उत्तर के बहुत नीचे "अविश्वसनीय या गलत कॉन्फ़िगर किए गए HTTPS साइटों से निपटने" अनुभाग भी देखें: Using java.net.URLConnection to fire and handle HTTP requests

+0

सिर्फ इस सवाल पाया ...... मैं एक ही समस्या है, लेकिन मैं अगर मैं मैं ग्रहण का उपयोग कर रहा CRT फाइल के साथ क्या करते हैं? ग्रहण के लिए keytool का विकल्प क्या है? – gedo

+0

स्पष्ट रूप से फ़ायरफ़ॉक्स डोमेन-स्तरीय प्रमाण पत्र के उपयोग को सबडोमेन पर जाने की अनुमति देता है। हालांकि, JSoup इस अनुमति नहीं देगा। इसे ठीक करने के लिए कोई सुझाव? – bvdb

+0

टिप के लिए धन्यवाद! अभी भी .jdk फ़ाइल लोड करने में कोई समस्या है .. ऐसा लगता है कि यह बाहरी/सीआरटी निर्देशिका से शामिल या एक्सेसिबल नहीं है। फ़ाइल f = नई फ़ाइल (Environment.getRootDirectory() + "/crt/www.loterie.lu.jks"); \t \t अगर (f.isFile()) \t \t \t Log.i ("JSOUP", "प्रमाणपत्र फ़ाइल मिली"); \t \t अन्य \t \t \t Log.i ("JSOUP", "त्रुटि: प्रमाणपत्र फ़ाइल नहीं मिली" + f.getAbsolutePath()); – Dax

0

मैं इस क्षेत्र में कोई विशेषज्ञ हूँ लेकिन java.net एपीआई का उपयोग कर HTTPS पर किसी वेबसाइट से कनेक्ट करने का प्रयास करते समय मैं एक समान अपवाद में भाग गया। जब आप HTTPS का उपयोग करते हुए किसी साइट पर जाते हैं तो ब्राउज़र SSL प्रमाणपत्रों के संबंध में आपके लिए बहुत अधिक काम करता है। हालांकि, जब आप मैन्युअल रूप से साइटों से कनेक्ट होते हैं (मैन्युअल रूप से HTTP अनुरोधों का उपयोग करके), तब भी जो काम अभी भी किया जाना चाहिए। अब मुझे नहीं पता कि यह सब काम बिल्कुल सही है, लेकिन इसे प्रमाणपत्र डाउनलोड करने और उन्हें कहां रखना है जहां जावा उन्हें ढूंढ सकता है। यहां एक लिंक है जो आपको उम्मीदवारों को सही दिशा में इंगित करेगा।

http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services

2

मुझे एक ही समस्या है लेकिन आलसी मार्ग लिया - अपने ऐप को प्रमाण को अनदेखा करने और वैसे भी आगे बढ़ने के लिए बताएं।

मैं यहाँ से कोड मिला:

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; 

बस कहीं उस विधि को चलाने से पहले आप कनेक्शन बनाने की कोशिश और देखा: How do I use a local HTTPS URL in java?

आप इन कक्षाओं में आयात करने के लिए यह काम करने के लिए होगा , यह सिर्फ प्रमाण पर भरोसा करता है चाहे कोई फर्क नहीं पड़ता। बेशक यह कोई मदद नहीं है यदि आप वास्तव में यह सुनिश्चित करना चाहते हैं कि प्रमाण वास्तविक है, लेकिन अपनी आंतरिक वेबसाइटों आदि की निगरानी के लिए अच्छा है।

7

मैंने यहां दिए गए उत्तरों और मेरे खोज में जुड़े प्रश्न में प्रश्नों पर ठोकर खाई जानकारी के दो टुकड़े जोड़ने के लिए, क्योंकि स्वीकार्य उत्तर मेरे समान परिदृश्य में फिट नहीं होता है, लेकिन एक अतिरिक्त समाधान भी है जो उस मामले में फिट बैठता है (प्रमाणपत्र और होस्टनाम परीक्षण सिस्टम के लिए मेल नहीं खाता है)।

  1. इस तरह के एक कार्यक्षमता जोड़ने के लिए एक GitHub अनुरोध नहीं है। तो शायद जल्द ही समस्या हल हो जाएगा: https://github.com/jhy/jsoup/pull/343 संपादित करें: Github अनुरोध हल किया गया था और प्रमाण पत्र सत्यापन निष्क्रिय करने के लिए विधि है: validateTLSCertificates (बूलियन सत्यापित करें)
  2. http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/ के आधार पर मैं एक समाधान है जो काम करने के लिए (कम से कम में लगता है पाया मेरी परिदृश्य जहां jsoup 1.7.3 को एक मेवेन कार्य के हिस्से के रूप में जाना जाता है)। मैंने इसे disableSSLCertCheck() विधि में लपेट लिया है जिसे मैं पहले Jsoup.connect() से पहले कॉल करता हूं। नहीं SSL प्रमाणपत्र की जाँच एक बहुत बेवकूफ बात है -

इससे पहले कि आप इस विधि उपयोग करते हैं, क्या तुम सच में लगता है कि आप समझते हैं कि तुम वहाँ क्या कर किया जाना चाहिए। हमेशा अपने सर्वर के लिए सही SSL प्रमाण पत्र का उपयोग करें जो आमतौर पर स्वीकृत सीए द्वारा हस्ताक्षरित होते हैं। यदि आप आमतौर पर स्वीकार किए गए सीए का सही एसएसएल प्रमाणपत्रों का उपयोग नहीं कर सकते हैं, फिर भी @ बालुससी ने ऊपर दिए गए उत्तर को स्वीकार किया है। आप सही SSL प्रमाणपत्र (जो उत्पादन वातावरण में मामला हो कभी नहीं करना चाहिए) कॉन्फ़िगर नहीं कर सकता, तो निम्न विधि काम कर सकता था:

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); 
    } 
+0

अगले पाठकों के लिए ... इसके साथ सावधान रहें: यह आपके ऐप में किसी भी कक्षा का व्यवहार बदलता है जो केवल आपके द्वारा चलाए जाने वाले वर्ग में, HttpsURLConnection का एक इरादा बनाता है। – exoddus

+0

मैं इस समाधान को Jsoup.connect (httpsurl) .get() विधि के साथ कैसे एकीकृत करूं? – Luke

-3

सिर्फ Jsoup.connect("https://example.com") से पहले डाल दिया निम्नलिखित का प्रयास करें (:

Authenticator.setDefault(new Authenticator() { 
     @Override 
     protected PasswordAuthentication getPasswordAuthentication() { 
      return new PasswordAuthentication(username, password.toCharArray()); 
     } 
    }); 
1

में मेरे मामले, सभी मुझे क्या करने की जरूरत है मेरी सिलसिले में .validateTLSCertificates (गलत) को जोड़ने के लिए था

Document doc = Jsoup.connect(httpsURLAsString) 
      .timeout(60000).validateTLSCertificates(false).get(); 

मैं भी पढ़ा टाइमआउट को बढ़ाने के लिए था, लेकिन मुझे लगता है कि यह अप्रासंगिक

0

मुझे जेएसओप के साथ एक ही समस्या का सामना करना पड़ रहा था, मैं https urls के लिए दस्तावेज़ कनेक्ट करने और प्राप्त करने में सक्षम नहीं था, लेकिन जब मैंने अपना जेडीके संस्करण 1.7 से 1.8 में बदल दिया, तो समस्या हल हो गई।

यह आप मदद कर सकते हैं :)

संबंधित मुद्दे