Обычная аутентификация с HTTPS - PullRequest
3 голосов
/ 09 июня 2011

В настоящее время я пытаюсь получить доступ к URL-адресу как по HTTP, так и по HTTPS. URL, к которому я пытаюсь получить доступ, требует базовой аутентификации. С HTTP он работает нормально, а с HTTPS - нет. Я не уверен, что есть что-то, что мне нужно добавить по-другому с HTTPS. URL должен возвращать мне текст в формате значения ключа, который я могу загрузить в Properties объект.

Вот код, который я пробовал до сих пор.

if (cpUrl.getProtocol().equals("https")) {
                        out.println("https", 0);
                        HttpsURLConnection connection = (HttpsURLConnection) cpUrl.openConnection();

                        TrustManager[] trustAllCerts = new TrustManager[] { new  BusinessIntelligenceX509TrustManager() };
                        SSLContext sc;

                        try {
                            sc = SSLContext.getInstance("SSL");
                        }
                        catch (NoSuchAlgorithmException noSuchAlgorithmException) {
                            return;
                        }

                        HostnameVerifier hv = new BusinessIntelligenceHostnameVerifier();

                        try {
                            sc.init(null, trustAllCerts, new java.security.SecureRandom());
                        }
                        catch (KeyManagementException keyManagementException) {

                            return;
                        }

                        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                        HttpsURLConnection.setDefaultHostnameVerifier(hv);

                        connection.setDoInput(true);
                        connection.setRequestProperty("Authorization", "Basic " + encode);

                        connection.setRequestMethod("POST");
                        connection.connect();
                        stream = connection.getInputStream();
                        Properties properties = new Properties();
                        properties.load(stream);

                    }

Вот сертификаты классов

   //HTTPS CERTIFICATE CLASSES
    class BusinessIntelligenceHostnameVerifier implements HostnameVerifier {

        public boolean verify(String arg0, SSLSession arg1) {
            return true;
        }

    }

    class BusinessIntelligenceX509TrustManager implements X509TrustManager {

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            // no-op
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            // no-op
        }

    }

Сообщение об ошибке при удалении всего кода сертификата (а также с кодом сертификата):

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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1518)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:818)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1030)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1057)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1041)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
    at com.tecsys.bi.install.BiInstall2ControlPanelPromptsProcessor.run(BiInstall2ControlPanelPromptsProcessor.java:117)
    at java.lang.Thread.run(Thread.java:595)
Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)
    at sun.security.validator.Validator.validate(Validator.java:203)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
    at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
    ... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
    ... 17 more

1 Ответ

3 голосов
/ 09 июня 2011

Проблема заключается в том, что соединение открыто до того, как экземпляры SSLContext и HostNameVerifier будут изменены для соединения.Это невозможно, поскольку квитирование SSL / TLS происходит даже до того, как содержимое соединения будет считано из InputStream.

Другими словами, следующая строка

HttpsURLConnection connection = (HttpsURLConnection) cpUrl.openConnection();

должнавыполнять только после того, как экземпляры SSLContext и HostNameVerifier s зарегистрированы в классе HttpsURLConnection.

HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);

Исправление этой последовательности должно исправить проблему, поскольку рукопожатие теперь будет происходить с использованиемновые параметры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...