繁体   English   中英

需要服务器名称指示(SNI)的测试服务器中的Apache CXF客户端错误

[英]Apache CXF client error in testing server which needs Server Name Indication (SNI)

我们有一个使用Apache CXF制作的客户端,可以使用某些服务器正常运行(即: https : //serverexample.com/application/webservice?wsdl )。

但是服务器已移至另一个IP,现在它在同一个IP中具有两个带有TLS和SNI(服务器名称指示)的SSL证书,现在我们的应用程序失败并出现以下错误:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching serverexample.com found

我知道,这是在https获取错误的证书(它具有另一个服务器名称)时发生的,因此与我的不匹配。

我试图找出openssl发生了什么,并且该URL仅在输入servername时有效:

# openssl s_client -connect serverexample.com:443 -tls1
Certificate chain
 0 s:/CN=otherserver.com/OU=Servers/O=MyOrganization/C=ES
   i:/CN=ACV20/OU=PKACV/O=ACV/C=ES

# openssl s_client -connect serverexample.com:443 -servername serverexample.com
Certificate chain
 0 s:/CN=serverexample.com/OU=Servers/O=MyOrganization/C=ES
   i:/CN=ACV220/OU=PKACV1/O=ACV2/C=ES

此时在生成的apache客户端中发生了错误:

final URL wsdlURL = new URL("https://serverexample.com/application/webservice?wsdl");
final Operation_Service ss = new Operation_Service(wsdlURL, SERVICE_NAME);

在新的Operation_Service中失败:

@WebServiceClient(name = "ENI.Operation", 
                  wsdlLocation = "https://serverexample.com/application/webservice?wsdl",
                  targetNamespace = "http://inter.ra.es/awrp/wsdl") 
public class Operation_Service extends Service {
    public final static URL WSDL_LOCATION;
    public final static QName SERVICE = new QName("http://inter.ra.es/awrp/wsdl", "ENI.Operation");
    public final static QName Operation = new QName("http://inter.ra.es/awrp/wsdl", "ENI.Operation");
    static {
        URL url = null;
        try {
            url = new URL("https://serverexample.com/application/webservice?wsdl");
        } catch (final MalformedURLException e) {
            java.util.logging.Logger.getLogger(Operation_Service.class.getName())
                .log(java.util.logging.Level.INFO, 
                     "Can not initialize the default wsdl from {0}", "https://serverexample.com/application/webservice?wsdl");
        }
        WSDL_LOCATION = url;
    }

     public Operation_Service(final URL wsdlLocation, final QName serviceName) {
        super(wsdlLocation, serviceName);
    }

javax.xml.ws.Service调用javax.xml.ws.spi.ServiceDelegate,这是一个由org.apache.cxf.jaxws中的某个类实现的抽象类。但是在这里我丢了它,我不知道该看...

我们的客户端在Weblogic 12.1.1.0上使用apache cxf 3.0.4在Java 7.0中运行。 我读到Java 6中存在SNI问题,但是我们在这里使用7.0。

我不知道该怎么办。 Java或客户端中是否有某些选项可以指示我们尝试连接的服务器名称(例如openssl)?

它是JDK 1.8中“改进”和服务器具有多个证书的事实的结合。

以下说明了JDK 1.8中的问题: http//lea-ka.blogspot.com/2015/09/wtf-collection-how-not-to-add-api.html

它是这样的:

  • 由于存在错误https://bugs.openjdk.java.net/browse/JDK-8072464而没有发送SNI扩展名。
  • 服务器返回证书“ CN = otherserver.com”,该证书也可能具有SAN(SubjectAlternativeName)“ otherserver.com”,而没有其他证书。
  • 将对JDK中的默认“ URL欺骗”检查进行检查,并比较URL中的“ serverexample.com”和证书中的“ otherserver.com”。 糟糕,您得到了例外。

最简单的解决方法是下载所有WSDL和XSD文件并将它们打包在jar中的某个位置。

如果您确实需要从远程服务器获取WSDL,这可能会有所帮助:

最终URL wsdlURL =新URL(“ https:// otherserver.com / application / webservice?wsdl”);

但这可能不起作用,因为“ / application / webservice”可能仅对serverexample.com已知。 在这种情况下,您将获得TLS连接,然后获得HTTP 404响应代码。

如果这样做不起作用,则您将不得不诉诸各种SSL工厂(这很冗长,但肯定是可能的),并尝试将它们挂接到javax.ws ....类中(应该可以,但我从未做过这部分) )。

希望这对您有帮助:

要解决SSL握手异常,可以选择2种方法:在代码开头设置此系统属性:

System.setProperty("jsse.enableSNIExtension", "false");

要么

将程序的VM参数设置为: -Djsse.enableSNIExtension=false

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM