【问题标题】:Trouble with securing a Tomcat/Axis2 web service via SSL通过 SSL 保护 Tomcat/Axis2 Web 服务的问题
【发布时间】:2011-12-22 19:34:02
【问题描述】:

我已经成功构建了一个有效的 Web 服务、客户端和 .jsp 驱动的 UI。我使用 Eclipse、Axis2、Tomcat 7 和 Java 7 完成了这项工作。

基本流程是用户访问 .jsp 并提交带有输入数据的表单。 JSP 将“请求”对象转发给 Java 客户端。 Java 客户端使用 Web 服务并提交用户输入。该服务通过 JDBC 连接到 SQL Server 数据库以检索信息,然后将这些信息显示给用户。

这一切都可以通过 HTTP 完美运行,但现在我想保护该过程,这就是我遇到问题的地方。我能够创建一个证书并让 Tomcat 使用它。我可以通过 HTTPS 连接到 Web UI 并提交表单并很好地取回数据。问题是这只是保护前端。 Web 服务客户端代码仍在后台通过 HTTP 连接到服务。

根据this page,我真正需要做的就是通过 SSL 启用我的连接服务是更新axis2.xml 文件并为HTTPS 包含一个新的“transportReceiver”节点。我这样做并重新生成了我的客户端代码以使用安全端点。它不起作用。

我已将 Tomcat 配置为侦听端口 8081(用于 http)和 8443(用于 https)。但是在将axis2.xml更改为匹配并启动Tomcat后,我得到以下信息:

[INFO] 监听 8443 端口 [ERROR] 终止连接 听众 org.apache.axis2.transport.http.server.DefaultConnectionListener@16d60567 在 0 秒内重试 10 次后。 java.net.BindException:地址已经 使用中:java.net.DualStackPlainSocketImpl.bind0 的 JVM_Bind(Native 方法)在 java.net.DualStackPlainSocketImpl.socketBind(Unknown 源)在 java.net.AbstractPlainSocketImpl.bind(未知源)在 java.net.PlainSocketImpl.bind(未知来源)在 java.net.ServerSocket.bind(未知来源)在 java.net.ServerSocket.(未知来源)在 java.net.ServerSocket.(未知来源)在 org.apache.axis2.transport.http.server.DefaultConnectionListener.run(DefaultConnectionListener.java:80) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 java.lang.Thread.run(Unknown Source)

我已经尝试更改axis2.xml 中的端口号(例如,更改为8445),这样就可以了。服务器能够干净地启动,但最终,同样的错误开始出现。例如,当我检索 WSDL 时,我通过控制台看到了错误(尽管 WSDL 确实出现了)。另外,如果我尝试在端口 8445 上实际使用该服务,我会收到以下错误:

org.apache.axis2.AxisFault:连接已关闭: javax.net.ssl.SSLException:无法识别的 SSL 消息,纯文本 连接?

我只能假设这是因为 Tomcat 被配置为在 8443 上处理 HTTPS,而不是 8445,但老实说我不知道​​。

如果我将端口保留为 8443 并在启动时忽略错误,则在连接到服务时会收到以下消息:

org.apache.axis2.AxisFault:连接已关闭: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:PKIX 路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException:无法 找到请求目标的有效认证路径

我关注these steps 试图让它识别我的证书,但是在将它导入我的 JRE7 密钥库时,我得到以下信息:

keytool 错误:java.lang.Exception:证书回复和证书 在密钥库中是相同的

基本上,该证书已经存在。这是有道理的,因为它是 Tomcat 已经成功使用的那个。

所以,我在这一点上很无知。我真的不确定我应该做什么。任何一般性指导或分步操作方法的链接都会非常有帮助。

但是对于一个特定的问题...当我在axis2.xml 中设置transportReceiver 节点时,我到底在做什么?我是在告诉它 Tomcat 运行在哪些端口上以及它应该使用哪些端口,还是 Axis2 有自己的服务器可以在这些端口上启动?似乎是后者,但这对我来说没有多大意义。

【问题讨论】:

    标签: java web-services tomcat ssl axis2


    【解决方案1】:

    Axis2 documentation 中描述了配置 servlet 传输的正确方法。您所描述的症状表明您有一个引用 org.apache.axis2.transport.http.SimpleHTTPServer 的 transportReceiver。另请确保您使用的是最新版本的 Axis2(1.5.6 或 1.6.1)。

    【讨论】:

    • 是的,就是这样!我将 transportReceiver 条目更改为使用 AxisServletListener,这解决了端口问题。谢谢!
    【解决方案2】:

    请参阅 Andreas 对端口问题的回复。至于证书问题,我对密钥库和信任库之间的区别存在误解。 JVM 默认使用 JAVA_HOME\lib\security\cacerts 作为其信任存储,而不是 USER_HOME\.keystore 文件。一旦我在那里导入我的证书,错误就消失了。

    我还能够通过代码明确地将信任库设置为密钥库文件来解决证书问题。我在将证书导入 cacerts 存储之前这样做了。它在调用服务之前进入客户端代码:

    System.setProperty("javax.net.ssl.trustStore","C:\\path\\to\\.keystore");
    System.setProperty("javax.net.ssl.trustStorePassword","password");
    

    【讨论】:

      【解决方案3】:

      连接 HTTPS 的一种方法是使用 jax-ws

      E:\WSDL>wsimport -keep -p com.mypack.webservice https://domain:port/ws/MyService?wsdl
      

      这将在 wsdl 文件夹下生成包结构。使用它。

      现在您所要做的就是将信任库放入run.bat 或使用System 类来设置属性。

      它会正常工作的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-09
        • 1970-01-01
        • 2012-05-18
        • 1970-01-01
        • 1970-01-01
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多