【问题标题】:JAX-WS Webservices, Load balancer with HTTPS End-point URL instead of HTTPJAX-WS Web 服务,使用 HTTPS 端点 URL 而不是 HTTP 的负载均衡器
【发布时间】:2013-03-13 13:40:57
【问题描述】:

我们公开了一个部署在负载均衡器后面的 Tomcat 实例上的 Web 服务。 Load-Balancer 只允许 HTTPS 流量,但 Jax-ws 端点指向 HTTP WSDL url 而不是 HTTPS。当客户端访问负载均衡器 HTTPS URL 时,它会被重定向到 HTTP,并且由于流量是 HTTP 在 LB 上被阻止,客户端会收到错误,因为 WSDL 无法访问。

sun-jaxws.xml 或 webservice 注释中是否有任何配置指定告诉 JAX-WS 公开 HTTPS url 而不是 HTTP。

下面是我的配置:

sun-jaxws.xml:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
version='2.0'>
<endpoint
    name='/TestService'
    implementation='com.test.service.TestServiceImpl'
    url-pattern='/TestService' />    

Annotation Config On WebService Impl class:

@WebService(serviceName="TestServiceImpl",
portName="TestService",
endpointInterface = "com.test.service.TestService",
targetNamespace="http://test.com"
)
@HandlerChain(file = "handlers.xml")
@MTOM
@XmlAccessorType(XmlAccessType.PROPERTY)
public class TestServiceImpl implements TestService{
//Implementation
}

如果有人能指出我正确的方向,那就太好了。

不同场景下的解决方案也请阅读评论

【问题讨论】:

  • 您是否尝试过指向 WSDL 的 SSL 版本,例如使用 server:ssl_port/web_service?WSDL 而不是基于 server:port/web_service?WSDL 创建客户端?部署 WS 时应自动创建 WSDL 的 SSL 版本(如果配置了服务器 SSL)。
  • 我指向的是 LoadBalancer 的 HTTPS url,但正如您在上图中看到的那样,WSDL url 指向的是 HTTP

标签: web-services jakarta-ee tomcat jax-ws load-balancing


【解决方案1】:

我不建议使用这种方法 - 更好的选择是终止负载平衡器上的 SSL 通信,并在负载平衡器和您的服务器之间使用纯 HTTP(除非您还需要保护平衡器和服务器之间的流量,但是我对此表示怀疑)。即,您不必在两个地方设置 SSL,并且当某些东西无法正常工作时,您会感到头疼。因此,首先尝试以这种方式配置负载均衡器。此外,您必须手动重写 WSDL 中的 &lt;soap:address location=".."&gt; 标记(当然,添加 HTTPS 地址)并从本地存储的 WSDL 生成 WS 客户端。

如果您仍想在 Tomcat 上设置 SSL,那么您首先必须设置密钥库 - 您的密钥和证书“数据库”。网上有很多教程怎么做,一个是here。然后,你需要通过添加这个 sn -p 来更改 Tomcat 的 server.xml 文件:

 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           keystoreFile="<PATH-TO-KEYSTORE>" keystorePass="<YOUR-KEYSTORE-PASSWORD>"
           clientAuth="false" sslProtocol="TLS"/>

最后,您需要指定您的 Web 服务将所有 HTTP 请求重定向到 HTTPS 侦听器 - 但在 web.xml 文件中,而不是在 sun-jaxws.xml 中:

<user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>

重启 Tomcat 就可以了。

【讨论】:

  • 正如你提到的,我不想在 LoadBalancer 和服务器之间进行 SSL 通信,我在 LB 和服务器之间只有普通的 HTTP 通信。但是当我访问 LoadBalancer 的 HTTPS url 例如:myloadbalalncer/Application/TestService,从 JAX-WS 生成的端点页面:WSDL url 指向 LoadBalancer 的 HTTP URL,并且由于 http 从客户端禁用到 LB , 客户端收到 Inaccesible WSDL 的错误
  • @John 您的情况下的平衡器似乎只是重定向了 HTTP 端口上的流量。如果配置正确,负载均衡器应该是透明的,客户端应该不知道它的存在。尝试以不同的方式配置它:要么只是将 HTTPS 传递给服务器(在这种情况下,您需要在 Tomcat 上启用 SSL),或者(更好)终止 SSL 连接并使用纯 HTTP 与服务器通信 - 而不仅仅是在 HTTP 上重定向流量,如您目前的情况。
  • 嗨 Miljen,我们需要实现你的第一个建议,Client 和 LB 之间的 HTTPS,LB 和 Server 之间的 HTTP。但是我们有和约翰一样的问题。 WSDL 描述符指向 HTTP 而不是 HTTPS,因此来自客户端的“第二次”调用是指向 http://... 所以它不起作用。如果您能举例说明如何实施您的第一个建议,我将不胜感激。
  • @Milijen,感谢您的快速回复。但问题是我使用注释来配置 WS,所以我没有要更改的 WSDL 文件。在这种情况下有没有办法编辑它?
  • @John 是的,那是平等的。如果您在 LB 和服务器之间使用 HTTP,这意味着您终止了平衡器上的 SSL 连接,这是最好的方法。关于这些要点,您可以在该链接上投票,如果您认为有帮助,可以投票/接受我的回答。
【解决方案2】:

另一种方法是在 Tomcat 的“server.xml”文件中添加这样的一行

<Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1" 
    connectionTimeout="20000"  scheme="https" proxyPort="443"
    redirectPort="8443" />

在这种情况下,使用 HTTP 将 LB 指向端口 8080。

当客户端使用 HTTPS 到端口 443 连接到 LB,LB 使用 HTTP 到端口 8080 连接到服务器时,这将起作用。在这种情况下,WSDL 返回

<soap:address location="https://www.yoursite.com:443/...">

重要的事情

scheme:将此属性设置为您希望通过调用 request.getScheme() 返回的协议的名称。例如,您可以将此属性设置为 SSL 的“https”连接器。默认值为“http”。

proxyPort:如果在代理配置中使用此连接器,请配置此属性以指定调用 request.getServerPort() 时要返回的服务器端口。

Jax-ws 使用粗体的两种方法来构建soap:address。

感谢奇诺在这方面的帮助!

【讨论】:

  • 有趣。当我们重定向到端口 8443 时,8443 的连接器配置是否应该包括密钥库和别名,例如:
  • 您只需要该行,无需将另一个连接器添加到端口 8443,因为不会有需要强制 SSL 到服务器的请求,因此我们不会调用该重定向.
猜你喜欢
  • 1970-01-01
  • 2013-08-26
  • 2017-06-12
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多