【问题标题】:Configuring Glassfish as a client of web services using mutual SSL使用相互 SSL 将 Glassfish 配置为 Web 服务的客户端
【发布时间】:2011-06-07 05:48:05
【问题描述】:

我正在尝试从需要客户端提供客户端证书的 Web 服务请求数据。服务器使用 SSL 进行所有通信,并使用自签名证书。我为 Netbeans 提供了服务的 WSDL 文件,它生成了带有 wsimport 的客户端代码。

当我的客户端代码是在常规 Java 应用程序中编写时,我没有任何问题;我将信任库设置为包含服务器证书的cacerts 文件,将密钥库设置为服务器管理员以 JKS 格式提供的文件,其中包含 2 个密钥 - 客户端私钥和服务器公钥,构建请求对象,然后发送请求。

当我将它转移到企业 Java 环境时,问题就来了。要求规定代码必须是在 Glassfish 应用服务器上运行的 Enterprise Archive 中的 Enterprise JavaBean。 Glassfish 似乎有自己的安全设置,可以覆盖 JVM 的设置。当包含 Web 服务调用的 EJB 方法运行时,SSL 协商失败:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target。我不知道如何像我的 JVM 设置一样设置 Glassfish 的安全设置,谁能解释 Glassfish 的安全设置?我所做的研究只展示了如何将 Glassfish 设置为 Web 服务 服务器,而不是 Web 服务 客户端

我有一个服务器的 .cer 证书文件,我使用 Java 的 keytool 将它添加到我的信任库中,将其添加到默认的 cacerts 文件中。 按照http://blog.johnryding.com/post/1548502059/acquire-an-ssl-certificate-for-your-java-programs-in-win 的步骤,用InstallCert 修改cacerts 文件以包含自签名证书会更好吗?

我有信任存储文件、密钥存储文件以及 .cer 证书文件和 .p12 浏览器证书,存储在 $JAVA_HOME/jre/lib/security 和 $JAVA_HOME/lib/security 中。

我正在使用 Netbeans 6.9.1 和 Glassfish 3.1 Final。下面是相关的代码,从我的 EJB 复制而来。异常发生在最后一行。

System.setProperty("javax.net.ssl.trustStore", "C:\\jssecacerts"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); System.setProperty("javax.net.ssl.keyStore", "C:\\userCertificate.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "password");
RequestObject request = new RequestObject;
request.setQuery("some data");
request.setUsername("user");
request.setPassword("pass");
Service service = new Service();
Endpoint port = service.getWebServicePort();
Result result = port.specificWebServiceMethod(request);

【问题讨论】:

  • 问题解决了吗??我也面临同样的情况。如果您有任何事情,请提供详细信息。

标签: authentication ssl jakarta-ee glassfish ejb


【解决方案1】:

我遇到了与上述 Jacques Pritchard 相同的例外:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

解决了它在 cacerts.jks 和 keystore.jks 中导入根证书,使用以下命令:

/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore cacerts.jks

/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore keystore.jks

重要的是,别名rootca 是我自己定义的用于标记证书的名称。您也可以选择任何名称。

【讨论】:

    【解决方案2】:

    您应该为您的客户创建一个单独的SSLContext,而不是使用全局系统属性。那么,它是否在 Glassfish 服务器中运行并不重要。

    这是一个应该相关的问题(关于 WS 的客户端证书):Choosing SSL client certificate in Java

    【讨论】:

      【解决方案3】:

      我遇到了这个确切的问题(使用 Glassfish 3.0.1)。

      以下是我们为解决此问题所采取的具体步骤。

        • 一个。使用 java keytool 命令查看密钥库以查看其中的内容。这有助于稍后查看是否有任何更改。该命令类似于

          keytool -list -keystore MyKeyStore.jks   
          
        • b.使用 openssl 将 pfx 转换为 pem。请注意,我为输入 pfx 使用了正确的密码,并为 pem 文件输出使用了与我的 java 密钥库相同的密码。

          openssl pkcs12 -in MyPfxFile.pfx -out MyPemFile.pem
          
      1. 将 pem 文件转换为 p12,可以轻松导入 java 密钥库。请注意,我在 java 密钥库中使用的密码与在输入和输出文件中使用的密码相同。

        openssl pkcs12 -export -in MyPemFile.pem -out MyP12File.p12
        
      2. 现在我终于将 p12 导入我的 java 密钥库。请注意,我使用的是 java 6,java 5 keytool 不支持 -importkeystore 参数。

        keytool -importkeystore -deststorepass MyPassword -destkeystore PathToMyKeystore/keystore.jks -srckeystore MyP12File.p12 -srcstoretype PKCS12 -srcstorepass MyPassword
        
      3. 您可以在此处列出密钥库内容,例如 keytool -list -keystore keystore.jks,以确保您的新密钥已正确导入。

      如果您像我一样幸运,您会发现此时启动您的应用服务器将毫无用处。您会看到类似 pkix 路径或 HTTP 403 Forbidden 之类的错误。

      上述步骤对 Sun Application Server 9.1_1 非常有效,但不适用于 Oracle Glassfish 3.0.1。与 Sun App Server 或 jdk 版本相比,我认为这与 ogs 3 中使用的 JSSE 版本有关。如果简单地将客户端证书添加到密钥库没有,将下面的 jvm 选项添加到您的 ogs 3 domain.xml 文件应该可以解决问题。

      <jvm-options>-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol</jvm-options>
      

      我确实注意到有人说不要使用上面的 jvm 选项语句,但它是修复的一部分,不要使用它,看看它是否有效,我敢打赌它不会。也许只是更改处理程序就是它起作用的原因?

      我在这里找到了详细信息:http://onjava.com/pub/a/onjava/2001/05/03/java_security.html?page=4

      我还偶然发现了最后一个问题(仅适用于 ogs 3),如果您时不时地失败,我建议您找到 InstallCert 应用程序(它在那里)并为其提供以下命令行参数: 每三次尝试调用 Web 服务时,我都会收到这些 PKIX 错误。

      希望这对其他人有所帮助。这些问题真的让我想扯掉我的头发:)

      【讨论】:

        【解决方案4】:

        我终于明白了。

        从我的 keytool 中删除了所有证书。

        命令示例:keytool -list -v -keystore keystore.jks -alias mydomain

        我将证书响应从服务器转换为 bas64 DER 并将它们复制到一个 .PEM 文件中,然后我将 .PEM 上传到我的密钥工具中:

        命令示例:keytool -importcert -keystore keystore.jks -alias mydomain -file my.pem

        然后我加载了密钥库:

        KeyStore myStore = KeyStore.getInstance("JKS");
        InputStream keyInputx = new FileInputStream("C:\\myStore.jks");
        myStore.load(keyInputx, "xxx".toCharArray());
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
        keyInputx.close();
        /*Enumeration enumeration = myStore.aliases();
         while (enumeration.hasMoreElements()) {
             String alias = (String) enumeration.nextElement();
             System.out.println("alias name: " + alias);
             Certificate certificate = myStore.getCertificate(alias);
             System.out.println(certificate.toString());
         }*/
        keyManagerFactory.init(myStore, "xxx".toCharArray());
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
        SSLSocketFactory sockFact = context.getSocketFactory();
        

        周围有很多参考资料,所以很乐意使用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-13
          • 2011-08-14
          • 2010-10-24
          • 2014-02-23
          • 2019-04-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多