有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

测试服务器中的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)


共 (2) 个答案

  1. # 1 楼答案

    它结合了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欺骗”检查是perofrmed,并比较URL中的“serverexample.com”和证书中的“otherserver.com”。哦,你有例外

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

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

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

    但这可能不起作用,因为“/application/webservice”可能只有serverexample知道。通用域名格式。在这种情况下,您将获得TLS连接,然后是HTTP 404响应代码

    如果这不起作用,您将不得不求助于各种SSL工厂(虽然很详细,但肯定是可能的),并尝试将它们连接到javax。ws。。。。课程(这应该是可能的,但我从来没有做过这部分)

  2. # 2 楼答案

    希望这对您有所帮助:

    对于解决SSL握手异常,您可以选择两种方式: 在代码开头设置此系统属性:

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

    或者

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