尽管将“disableCNCheck”设置为true,但https URL主机名与公共名称(CN)不匹配

问题描述 投票:9回答:3

我设法正确配置基于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不匹配,但在我的情况下,既不起作用也不起作用。

为什么?

java web-services ssl https cxf
3个回答
8
投票

我在几个实例中使用过CXF

<http:tlsClientParameters disableCNCheck="true">

足以禁用CN检查。

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

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

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

Update 2 Jan 2015

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

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

该名称包括服务的名称空间,WSDL端口名称(在WSDL的wsdl:service部分中找到)和“.http-conduit”。它遵循以下模板:

{WSDL Namespace}portName.http-conduit

注意:它是PORT名称,而不是服务名称。

..

name属性的另一个选项是端点的ORIGINAL URL的reg-ex表达式(例如,“http://myserver.example.com:*”)。配置在管道创建时匹配,因此WSDL中使用的地址或用于JAX-WS Service.create(...)调用的地址可用于名称。


2
投票

-Djsse.enableSNIExtension=false放入您的appserver VM Options中。


1
投票

添加以下代码以设置disableCNCheck

 HTTPConduit httpConduit=(HTTPConduit)ClientProxy.getClient(port).getConduit();
        TLSClientParameters tlsCP = new TLSClientParameters();
        tlsCP.setDisableCNCheck(true);
        httpConduit.setTlsClientParameters(tlsCP);

仅在较低的环境中使用此代码。在较高的环境中,不建议使用此代码。

© www.soinside.com 2019 - 2024. All rights reserved.