java - 尽管将 'disableCNCheck' 设置为 true,但 https URL 主机名与通用名称 (CN) 不匹配

标签 java web-services ssl https cxf

我设法正确配置了基于 CXF 的客户端,以便它为我运行 Web 服务的服务器找到正确的 SSL 证书:

  <http:conduit name="https://myserver/myws/register/soap?wsdl:{http://glob.reg.com/myws}.http-conduit">

    <http:tlsClientParameters>
      <sec:keyManagers keyPassword="changeit">
        <sec:keyStore type="JKS" password="changeit"
                  file="C:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"/> 
       </sec:keyManagers>
      <sec:trustManagers>
        <sec:keyStore type="JKS" password="changeit"
                  file="C:\Program Files (x86)\Java\jdk1.6.0_45\jre\lib\security\cacerts"/> 
      </sec:trustManagers>
      <sec:cipherSuitesFilter>
        <!-- these filters ensure that a ciphersuite with
             export-suitable or null encryption is used,
             but exclude anonymous Diffie-Hellman key change as
             this is vulnerable to man-in-the-middle attacks -->
        <sec:include>.*_EXPORT_.*</sec:include>
        <sec:include>.*_EXPORT1024_.*</sec:include>
        <sec:include>.*_WITH_DES_.*</sec:include>
        <sec:include>.*_WITH_AES_.*</sec:include>
        <sec:include>.*_WITH_NULL_.*</sec:include>
        <sec:exclude>.*_DH_anon_.*</sec:exclude>
      </sec:cipherSuitesFilter>
    </http:tlsClientParameters>
    <http:authorization>
      <sec:UserName>Betty</sec:UserName>
      <sec:Password>password</sec:Password>
    </http:authorization>
    <http:client AutoRedirect="true" Connection="Keep-Alive"/>

  </http:conduit>

但是...因为证书是针对与我的服务器机器不同的子域名(映射到相同的 IP 地址),我收到以下错误:

Caused by: java.io.IOException: The https URL hostname does not match the Common Name (CN) on the server certificate in the client's truststore.  Make sure serv
er certificate is correct, or to disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1234)
        at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:183)
        at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
        at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1293)
        ... 18 more

所以...因为这是一个开发/测试系统,我按照建议的消息做了(将 CXF 客户端 TLS 配置属性“disableCNCheck”设置为 true):

<http:tlsClientParameters disableCNCheck="true">

另外,我将以下代码添加到我客户的主类中(根据建议 in this thread ):

  static {
    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
    {
      @Override
      public boolean verify(String hostname, SSLSession session)
      {
        return true;
      }

    });    
  }

但是......我仍然遇到同样的错误:

Caused by: java.io.IOException: The https URL hostname does not match the Common Name (CN) on the server certificate in the client's truststore.  Make sure serv
er certificate is correct, or to disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1234)
        at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:183)
        at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
        at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1293)
        ... 18 more

知道为什么吗?

我的意思是,上述解决方法之一应该足以让客户端忽略证书 URL 不匹配,但在我的情况下,无论是它们还是它们的组合都不起作用

为什么?

最佳答案

我在几个实例中使用了 CXF

<http:tlsClientParameters disableCNCheck="true">

足以禁用 CN 检查。

您确定您的客户正在使用该管道配置吗?我的理解是管道名称模式需要以某种方式匹配端点 URI。

尝试按如下方式设置管道名称,以便任何端点都匹配并查看是否有任何改变:

<http:conduit name="*.http-conduit">

2015 年 1 月 2 日更新

事实证明,http-conduit 配置名称匹配有两种模式格式。一个涉及服务的命名空间和端口名称。另一种支持的格式是与 WSDL 中指定的 URL 端点匹配的正则表达式,用于创建客户端。

引用 Apache CXF User Guide关于 http-conduit 元素:

The name includes the service's namespace, the WSDL port name (as found in the wsdl:service section of the WSDL), and ".http-conduit". It follows this template:

{WSDL Namespace}portName.http-conduit

Note: it's the PORT name, not the service name.

..

Another option for the name attribute is a reg-ex expression (e.g., "http://myserver.example.com:*") for the ORIGINAL URL of the endpoint. The configuration is matched at conduit creation so the address used in the WSDL or used for the JAX-WS Service.create(...) call can be used for the name.

关于java - 尽管将 'disableCNCheck' 设置为 true,但 https URL 主机名与通用名称 (CN) 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21120264/

相关文章:

r - 在 blogdown 中安装 Hugo 时出现 SSL 错误

node.js - 用于负载均衡器类型服务的 Kubernetes SSL

ssl - 如何使用 httparty ruby​​ gem 验证 ssl 证书?

java - 使用基于计数的窗口连接两个流

web-services - 使用生产代码部署配置文件

java - Java 中 JSON 字符串中的 HTML

c# - 返回值后执行代码行

java - 从大 WSDL 文件生成 Java 客户端

java - BufferedImage 比较显示奇怪的行为

java - 循环SQL语句