HttpsURLConnection: использование IDE JDK работает для аутентификации, но не с JRE !! Это странно - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть приложение, которое использует HttpsURLConnection с файлом pfx и сессионным поваром ie для получения информации о веб-странице.

Вопрос в том, работает ли я, запустив jar следующим образом:

"C:\Program Files\Java\jdk1.8.0_111\bin\java.exe" -jar "app"

Но это не работает, если я запускаю банку с моей JRE, с:

 java -jar "app.jar"

Это просто не аутентифицируется ...

Я читал об этом: Как обеспечить аутентификацию ntlm при вызове любого URL?

Но отключение этого ограничения JRE "NTLM" мне не помогло. И насколько я знаю, я не использую "NTLM".

Спасибо тебе ...

   public void connect() {

    try {
        URL url = new URL(HTTPS_URL);
        conn = (HttpsURLConnection) url.openConnection();
        conn.setSSLSocketFactory(getFactory(new File(KEY_STORE_FILE), KEY_STORE_PASS, new File(TRUST_STORE_FILE), TRUST_STORE_PASS));
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Accept-Language", "es,es-ES;q=0.9,en;q=0.8,de;q=0.7");
        conn.setInstanceFollowRedirects(true);

        if (!cookies.isEmpty()) {
            for (Map.Entry<String, String> entry : cookies.entrySet()) {
                if (entry.getKey() != null && entry.getValue() != null) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
        }

        conn.connect();

        this.headers = conn.getHeaderFields();

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;

        while ((line = br.readLine()) != null) {
            responsebody += line;
        }

        br.close();

    } catch (MalformedURLException e) {
        System.out.println(e.toString());
        e.printStackTrace();
    } catch (SSLPeerUnverifiedException e) {
        System.out.println(e.toString());
        e.printStackTrace();
    } catch (IOException e) {
        System.out.println(e.toString());
        e.printStackTrace();
    }

}


    private SSLSocketFactory getFactory(File pKeyFile, String pKeyPassword, File pTrustStoreFile, String pTrustStorePassword) {

    SSLSocketFactory socketFactory = null;

    try {
        KeyManagerFactory keyManagerFactory;
        keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_ALGORITHM);
        KeyStore keyStore;
        keyStore = KeyStore.getInstance(KEY_STORE_FORMAT);
        InputStream keyInput = new FileInputStream(pKeyFile);

        keyStore.load(keyInput, pKeyPassword.toCharArray());
        keyInput.close();
        keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_ALGORITHM);
        KeyStore trustStore;
        trustStore = KeyStore.getInstance(TRUST_STORE_FORMAT);
        InputStream trustStoreInput = new FileInputStream(pTrustStoreFile);
        trustStore.load(trustStoreInput, pTrustStorePassword.toCharArray());
        trustStoreInput.close();
        trustManagerFactory.init(trustStore);

        SSLContext context = SSLContext.getInstance(SSL_CONTEXT_ALGORITHM);
        context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
        socketFactory = context.getSocketFactory();

    } catch (IOException e) {
        if (e.toString().contains("keystore password was incorrect")) {
            System.out.println("Contraseña del certificado inválida: " + pKeyFile.getName());
        }
        System.out.println(e.toString());
        e.printStackTrace();
    } catch (Exception e) {
        System.out.println(e.toString());
        e.printStackTrace();
        return (socketFactory);
    }
    return socketFactory;
}

1 Ответ

1 голос
/ 13 апреля 2020

Я решил, я спрашиваю себя, могу ли я кому-нибудь помочь:

Проблема заключалась в том, что я использовал следующее предложение:

conn.setInstanceFollowRedirects(true);

И на удаленном хосте были перенаправления на поддомен с другим IP-адресом. Таким образом, в более новой версии JDK было добавлено ограничение, заключающееся в том, что вы не можете иметь перенаправления на разные IP-адреса ... Он очищает все данные вашего запроса. Вот почему в версии JDK мое приложение работало, а в более новых версиях оно не работало.

Мой обходной путь для следования перенаправлениям без .instanceFollowRedirects:

    Map<String,List<String>> headers = conn.getHeaderFields();
    if (headers.containsKey("Location")){
        return cert_request(headers.get("Location").get(0),KEY_STORE_FILE,KEY_STORE_PASS,TRUST_STORE_FILE,TRUST_STORE_PASS,cookie);
    }

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

...