Jsoup website login выбрасывает неизвестное исключение


Я пытаюсь войти на веб-сайт моей школы, чтобы отобразить HTML со следующим кодом:

public class Connect {



public static void main(String[] args) {

    String pageURL = "https://parents.mtsd.k12.nj.us/genesis/parents?tab1=studentdata&action=form";
    String param1 = "&tab2=gradebook";
    String param2 = "&tab3=weeklysummary";
    String param3 = "&studentid=";
    Scanner input = new Scanner (System.in);
    String initURL = "https://parents.mtsd.k12.nj.us/genesis/parents?gohome=true";




    //System.out.print("Enter Student ID: ");
    //String sID = input.nextLine();
    String sID = "not shown";

    String URLF = pageURL + param1 + param2 + param3 + sID;

    connectTo(URLF);


    // write your code here
}

public static Document connectTo (String URLF){

    String loginURL = "https://parents.mtsd.k12.nj.us/genesis/parents/j_security_check";
    String userDataUrl = URLF;
    String username = "not shown";
    String password = "not shown";

    Connection.Response res = null;
    Document doc = null;

    try {

        res = Jsoup.connect(userDataUrl)
                .userAgent("Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.4 Safari/537.36")
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
                .timeout(500)
                .method(Connection.Method.GET)
                .execute();

    } catch (IOException io) {

        io.printStackTrace();

    }

    try {

        doc = Jsoup.connect(loginURL)
                .userAgent("Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.4 Safari/537.36")
                .referrer("https://parents.mtsd.k12.nj.us/genesis/parents?gohome=true")
                .cookies(res.cookies())
                .data("j_username", username)
                .data("j_password", password)
                .post();


    } catch (IOException ioe) {

        ioe.printStackTrace();

    }

    if (doc != null){
        System.out.print(doc.text());
    }
    return null;
}
}

Однако, когда я запускаю это, я получаю следующую ошибку:

javax.net.ssl.SSLHandshakeException:  sun.security.validator.ValidatorException: PKIX path building failed:  sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1506)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at  sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDele gateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:512)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:493)
at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:205)
at com.gs.Connect.connectTo(Connect.java:58)
at com.gs.Connect.main(Connect.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:146)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 26 more
Exception in thread "main" java.lang.NullPointerException
at com.gs.Connect.connectTo(Connect.java:71)
at com.gs.Connect.main(Connect.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Теперь я не уверен, почему это не работает, поскольку я использую этот аналогичный процесс (с Jsoup) для входа/анализа информации с подобных сайтов, и я не сталкивался ни с какими проблемами. Любая помощь ценится!

1 3

1 ответ:

Краткое объяснение происхождения execpetion unable to find valid certification path to requested target.

Java установит безопасные соединения по протоколу SSL только в том случае, если она доверяет сертификату. Сертификаты, являющиеся доверительными, хранятся в хранилище truststore ${JAVA_HOME} / lib / security / cacerts. Доверительное хранилище содержит список известных центров сертификации (CA). Если сертификат удаленного сервера не подписан ни одним из центров сертификации в доверительном хранилище, ни сертификат самого удаленного сервера находится в доверительном хранилище, то соединение не будет доверительным и SunCertPathBuilderException будет брошено.

В этом случае сертификат подписан GoDaddy.com, который не находится в доверительном хранилище Java. Так что придется вручную добавить сертификат сервера либо в стандартный Java trustore, либо в отдельный your_keystore.jks.

Ниже описано, как загрузить сертификат сервера и сохранить его в отдельном хранилище ключей. Это хранилище ключей затем будет использоваться для проверки сертификата сервера.

Не делайте этого с помощью default для всех не доверенных соединений Java. Прежде чем сделать это, вы должны убедиться, что сервер, к которому вы подключаетесь, является тем, к которому вы хотите подключиться.


Сначала вам нужно загрузить сертификат этой веб-страницы.

Например, использование браузера Chrome (шаги, описанные для Linux, Windows аналогичны, OSX проверьте комментарии ниже):

  • открыть веб-страницу https://parents.mtsd.k12.nj.us
  • нажмите на значок замка в адресной строке (перед https://)
  • в диалог нажмите на вкладку Connection
  • нажмите на ссылку Certificate information
  • в Certificate Viewer нажмите на вкладку details
  • нажмите на кнопку Export и сохраните сертификат в формате BASE 64 encoded single certificate как файл owa.mtsd.us.b64 (может быть любое другое имя файла)

шаги 1-4 шаги 5-6

Далее создайте файл хранилища ключей (одна командная строка)

keytool -import -noprompt -trustcacerts \
    -alias owa.mtsd.us -file owa.mtsd.us.b64 \
    -keystore your_keystore.jks -storepass YourPasswd

Следующий фрагмент успешно установил соединение

// without setting your created keystore
// a sun.security.validator.ValidatorException will be thrown
System.setProperty("javax.net.ssl.trustStore", "your_keystore.jks");
String url = "https://parents.mtsd.k12.nj.us";
Document doc = Jsoup.connect(url).get();
System.out.println("doc = " + doc.text());

Вывод

doc = One Moment...