【问题标题】:Basic authentication with HTTPS使用 HTTPS 的基本身份验证
【发布时间】:2011-06-09 12:30:30
【问题描述】:

我目前正在尝试使用 HTTP 和 HTTPS 访问 URL。我尝试访问的 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

【问题讨论】:

  • 你的代码哪里出错了?它是否在连接设置、基本身份验证或其他地方失败?
  • 加载属性时失败。它说那里什么都没有。即使有。
  • 另一方面,以演示的方式实现主机名验证器和信任管理器类是多余且不安全的。如果您的 cacerts 文件已经加载了适当的证书,那么 SSL/TLS 设置阶段应该没有问题。
  • >'如果还需要什么,请告诉我。' -- 错误信息,偏离路线
  • 我想你的意思是这一行 - properties.load(stream);

标签: java url https


【解决方案1】:

问题似乎在于连接已打开,在 SSLContextHostNameVerifier 实例更改连接之前。这是不可能的,因为 SSL/TLS 握手甚至在从 InputStream 读取连接内容之前就发生了。

换句话说,下面一行

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

应该仅在 SSLContextHostNameVerifiers 实例已注册到 HttpsURLConnection 类之后执行。

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

修复这个序列,应该可以解决问题,因为现在将使用新参数进行握手。

【讨论】:

  • @RMT,不客气。在您上次更新后,我注意到您的自定义信任管理器和主机名验证器未用于解析证书信任路径。那一点信息,就是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 1970-01-01
  • 2015-08-12
  • 2013-03-17
  • 1970-01-01
相关资源
最近更新 更多