【问题标题】:Not able to access the HTTPS web service sitting behind a HTTPS load balancer无法访问位于 HTTPS 负载平衡器后面的 HTTPS Web 服务
【发布时间】:2015-03-16 12:09:42
【问题描述】:

我正在开发一个 Web 服务客户端来访问位于 HTTPS 负载平衡器后面的 HTTPS Web 服务。但我遇到了一个例外。

    com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.
    java.io.IOException: Got java.security.cert.CertificateException: No subject alternative names present while opening stream from https://HOST:PORT/itim/services/WSSessionService/WEB-INF/wsdl/WSSessionService.wsdl
    java.io.IOException: Got java.security.cert.CertificateException: No subject alternative names present while opening stream from https://HOST:PORT/itim/services/WSSessionService/WEB-INF/wsdl/WSSessionService.wsdl?wsdl

HOSTPORT是负载均衡器的IP地址和端口。

我可以从浏览器访问这个 URL - https://HOST:PORT/itim/services/WSSessionService/WEB-INF/wsdl/WSSessionService.wsdl

但不是这个 - https://HOST:PORT/itim/services/WSSessionService/WEB-INF/wsdl/WSSessionService.wsdl?wsdl

我忽略了使用此代码的证书 -

    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
        public X509Certificate[] getAcceptedIssuers(){return null;}
        public void checkClientTrusted(X509Certificate[] certs, String authType){}
        public void checkServerTrusted(X509Certificate[] certs, String authType){}
    }};

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        ;
    }

这是完整的堆栈跟踪:

    [ERROR   ] SRVE0777E: Exception thrown by application class 'com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex:196'
    com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.

    java.io.IOException: Got java.security.cert.CertificateException: No subject alternative names present while opening stream from https://HOST:PORT/itim/services/WSSessionService/WEB-INF/wsdl/WSSessionService.wsdl
    java.io.IOException: Got java.security.cert.CertificateException: No subject alternative names present while opening stream from https://HOST:PORT/itim/services/WSSessionService/WEB-INF/wsdl/WSSessionService.wsdl?wsdl

at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:196)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:168)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:133)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:272)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:235)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:183)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:101)
at javax.xml.ws.Service.<init>(Service.java:89)
at com.ibm.itim.ws.services.WSSessionService_Service.<init>(WSSessionService_Service.java:50)
at examples.ws.GenericWSClient.getSessionService(GenericWSClient.java:150)
at examples.ws.MyServlet.doGet(MyServlet.java:59)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1240)
at [internal classes]

【问题讨论】:

    标签: java web-services wsdl


    【解决方案1】:

  • 创建 自签名证书,就像这样:
    keytool -genkey -alias YOUR_ALIAS -keyalg RSA -keystore YOUR_PATH_KS
  • 当它要求您输入“名字和姓氏”时,请输入您的 HOST_NAME
  • 导出从您新创建的密钥库中的证书:
    keytool -exportcert -alias -file YOUR_PATH_CERTIFICATE -keystore YOUR_PATH_KS
  • 导入您的证书到“Trusted Ca Certs
    cd %JAVA_HOME%\jre\lib\security
    keytool -import -trustcacerts -keystore cacerts -alias YOUR_HOSTNAME -file YOUR_PATH_CERTIFICATE
    

  • 【讨论】:

    • CN应该是Web服务服务器的主机名还是负载均衡器的主机名?
    【解决方案2】:

    你的 SSLCONtext 不应该用“SSL”而不是“TLS”来初始化吗? SSLContext sc = SSLContext.getInstance("SSL");
    另外,请尝试添加主机名验证器:
    HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String hostname, SSLSession arg1) { if (hostname.equals("your host ip") return true; return false; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv);

    请注意,这是一种解决方法。需要发生的是,必须使用具有主题备用名称条目的网络的 CN 和 DNS 名称生成证书,即 san=ip:your host。这可能是实际的解决方案。

    【讨论】:

    • 我已将上述代码 (HostnameVerifier....) 包含在一个静态块中,但仍然出现相同的错误。该代码在本地环境中运行良好,但是当我尝试在 Bluemix(IBM 的 PaaS)上运行它时,它给了我同样的错误。
    • 好的,很高兴你让它以其他方式工作。我对 Bluemix 的网络验证一无所知。 ://
    【解决方案3】:

    感谢您的回答,但我只需在 hosts 文件中添加一个条目即可解决此问题。

        ip_address     example.com
    

    example.com 是证书的 CN

    【讨论】:

      猜你喜欢
      • 2019-04-22
      • 1970-01-01
      • 2014-12-11
      • 2011-01-06
      • 2014-03-21
      • 2019-03-11
      • 2013-08-26
      • 1970-01-01
      • 2018-12-15
      相关资源
      最近更新 更多