测试服务器中的java Apache CXF客户端错误,需要服务器名称指示(SNI)
我们有一个使用ApacheCXF制作的客户端,它工作正常,使用特定的服务器(即: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);
在新操作\u服务中失败:
@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。服务调用javax。xml。ws。spi。ServiceDelegate,由组织中的某个类实现的一个抽象类。阿帕奇。cxf。jaxws。。但在这里我失去了它,我不知道该看什么
我们的客户机在weblogic 12.1.1.0上运行java 7.0和apache cxf 3.0.4。我读到在Java6中SNI有问题,但我们在这里使用的是7.0
我不知道我能做什么。在java或我们的客户机中是否有一些选项来指示我们尝试连接的服务器名(如openssl)
# 1 楼答案
它结合了JDK 1.8中的“改进”和服务器拥有多个证书的事实
JDK 1.8中的漏洞如下所述: http://lea-ka.blogspot.com/2015/09/wtf-collection-how-not-to-add-api.html
事情是这样的:
最简单的解决方法是下载所有WSDL和XSD文件,并将它们打包到jar中的某个地方
如果您确实需要从远程服务器获取WSDL,这可能会有所帮助:
最终URL wsdlURL=新URL(“https://otherserver.com/application/webservice?wsdl”)
但这可能不起作用,因为“/application/webservice”可能只有serverexample知道。通用域名格式。在这种情况下,您将获得TLS连接,然后是HTTP 404响应代码
如果这不起作用,您将不得不求助于各种SSL工厂(虽然很详细,但肯定是可能的),并尝试将它们连接到javax。ws。。。。课程(这应该是可能的,但我从来没有做过这部分)
# 2 楼答案
希望这对您有所帮助:
对于解决SSL握手异常,您可以选择两种方式: 在代码开头设置此系统属性:
System.setProperty("jsse.enableSNIExtension", "false");
或者
将程序的VM参数设置为:
-Djsse.enableSNIExtension=false