6

免责声明:我试过谷歌搜索可以做我想做的事情,但没有运气。我希望这里有人可以伸出援手。

背景

我有一个使用 WSE 2.0 库访问安全 Web 服务的 .NET 类库。Web 服务为中央数据库提供了一个前端(它实际上是跨越多个客户的数据共享网络的一部分),并且类库提供了一个简单的 Web 服务调用包装器,以使其可以从旧版 VB6 应用程序中访问。遗留应用程序使用类库来检索信息并将其发布到 Web 服务。目前,应用程序和类库 DLL 都安装在多个工作站的客户端。

问题

问题是我们正在访问的 Web 服务使用 HTTPS,并且需要向 Web 服务提供有效的 X509 客户端证书才能访问它。由于我们所有的组件都存在于客户端机器上,这导致了部署问题。例如,我们必须在每台客户端机器上下载并安装每个用户的证书,每个用户可能需要通过我们的应用程序访问 Web 服务。此外,Web 服务器本身必须通过 VPN(尤其是 OpenVPN)访问,这意味着必须在每台客户端计算机上安装和配置 VPN 客户端。这是一个主要的痛苦(我们的一些客户有几十个工作站)。

建议的解决方案

建议的解决方案是将所有这些逻辑移动到客户站点上的中央服务器。在这种情况下,我们的遗留应用程序将与本地服务器通信,然后该服务器将关闭并将请求转发到真正的 Web 服务。此外,作为简化和集中部署工作的一部分,所有 X509 证书都将安装在服务器上,而不是安装在每台单独的客户端计算机上。

到目前为止,我们提出了三个选项:

  • 找到一个现成的 SOAP 代理服务器,它可以接收基于 HTTP 的 SOAP 请求,修改HostSOAP 消息的标头和路由相关部分(因此它们指向真实的 Web 服务器),打开到真实 Web 的 SSL 连接服务器,向服务器提供正确的客户端证书(基于用户名到证书的映射),转发修改后的请求,读取响应,将其转换回纯文本,然后将其发送回客户端。
  • 手动编写一个代理服务器来完成我刚才提到的所有事情。
  • 想出完全不同的、有希望更好的方法来解决这个问题。

基本原理

尝试查找和/或编写 SOAP 代理服务器的基本原理是根本不需要修改我们现有的 .NET 包装库。我们只需将其指向代理服务器而不是真正的 Web 服务端点,使用普通的 HTTP 连接而不是 HTTPS。代理服务器将处理请求,修改它以使真正的 Web 服务接受它(即更改SOAPAction标头以使其正确),处理 SSL/证书握手,并将原始响应数据发送回客户。

然而,这对我来说充其量是一个可怕的黑客攻击。那么,我们在这里的选择是什么?

  • 我是否咬紧牙关编写自己的 HTTP/SSL/SOAP/X509 感知代理服务器来完成这一切?
  • 或者...是否有一个具有足够可扩展 API 的现成解决方案,我可以轻松地让它做我想做的事
  • 或者……我应该采取完全不同的方法吗?

我们试图解决的关键问题是 (a) 集中存储证书的位置以简化证书的安装和管理,以及 (b) 进行设置以便 VPN 连接到 Web 服务器只发生在单台机器上,而不是需要每个客户端都安装了 VPN 客户端软件。

请注意,我们不控制托管 Web 服务的 Web 服务器。

编辑:为了澄清,我已经在 C# 中实现了一个(相当糟糕的)代理服务器,它确实满足了要求,但是我对这个问题的整个方法感觉根本上是错误的。所以,最终,我正在寻找让我确信我在正确的轨道上的保证,或者有用的建议告诉我我正在以完全错误的方式解决这个问题,以及以更好的方式做这件事的任何提示(如果有的话,我怀疑有)。

4

6 回答 6

5

Apache Camel 完全符合要求。Camel 是一个轻量级框架,用于进行这种应用程序集成。过去我用它来做一些类似的http代理。

Camel 使用非常富有表现力的 DSL 来定义端点之间的路由。在您的情况下,您希望建立一个对客户站点上的所有客户端计算机可见的服务器,并且无论它收到什么请求,您都希望通过 https 将“从”此端点“路由到”您的安全端点。

您需要创建一个定义路由的简单类。它应该扩展 RouteBuilder 并覆盖配置方法

public class WebServiceProxy extends RouteBuilder
{
    public void configure()
    {
       from("jetty:http://0.0.0.0:8080/myServicePath")
                  .to("https://mysecureserver/myServicePath");
    }
}

将此添加到 Camel 上下文中,您就可以开始了。

CamelContext context = new DefaultCamelContext();
context.addRoute(new WebServiceProxy());
context.start();

此路由将在所有本地接口上使用绑定到 8080 的码头创建一个网络服务器。发送到 /myServicePath 的任何请求都将直接路由到由 uri 定义的 Web 服务https://mysecureserver/myServicePath。您使用简单的 uris 定义端点,dsl 和骆驼负责繁重的工作。

您可能需要配置一个包含您的证书的密钥库,并使其可用于 http 组件。如果您在这里遇到麻烦,请再次发布;)

我会阅读 http 组件的骆驼文档以获取更多详细信息,也请检查项目的单元测试,因为它们充满了示例和最佳实践。

HTH。

仅供参考:要让 http 组件使用您的密钥库,您需要设置以下属性

System.setProperty("javax.net.ssl.trustStore", "path/to/keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "keystore-password");
于 2009-05-29T03:54:42.473 回答
2

您应该查看支持 WS-Addressing 协议的 WCF。我相信我已经看过关于使用 WCF 编写路由器的文章(我认为是在 MSDN 中)。

您还应该尽快摆脱 WSE 2.0。它已经过时了(已被 WSE 3.0 取代,它也已过时)。它的所有功能都已被 WCF 取代。

于 2009-05-29T09:10:03.377 回答
1

我相信 ESB(企业服务总线)可能是解决您的问题的可行、强大的解决方案。有一个名为Mule的开源 ESB ,我从未使用过。前段时间我确实搞砸了ALSB(AquaLogic 服务总线),但对于您所描述的而言,它会很昂贵。无论如何,您要特别关注的是路由。我不确定这会是一个简单的即插即用,但它确实是另一种选择。

于 2009-05-29T03:32:15.337 回答
1

您也可以使用商业代理/缓存服务器Microsoft ISA Server来执行此操作。它会做很多你需要开箱即用的事情。对于开箱即用不可能的任何事情,您可以为服务器编写一个扩展来完成它。

ISA Server 不是免费的。

ISA 现在更名为“Microsoft Forefront Threat Management Gateway”。

不过,它不仅仅是一个网络代理服务器——它支持许多协议和许多功能。也许比你需要的更多。

于 2009-05-29T08:59:40.153 回答
0

你的安全模型对我来说没有意义。使用 HTTPS 的目的是什么?通常是向客户端验证服务。在那种情况下,为什么服务器需要保留客户端的证书?应该保留服务器的 X509 证书的是客户端。

为什么需要通过VPN?如果您需要对客户端进行身份验证,有更好的方法可以做到这一点。您可以在 SSL 中启用相互身份验证,或者使用 XML-Security 和可能的 WS-Security 在 SOAP 级别保护服务。即使您确实使用 SSL 对客户端进行身份验证,您仍然不应将所有客户端证书保留在服务器上,而应使用 PKI 并将客户端证书验证到受信任的根。

最后,特别是对于您提出的基于代理的解决方案,我不明白为什么您需要任何特定于 SOAP 的东西。您不只需要一个可以将任何 HTTP 请求转发到远程 HTTPS 服务器的 Web 服务器吗?我不知道该怎么做,但我会调查 Apache 和 IIS 之类的...

于 2009-05-29T03:34:51.370 回答
0

Codeplex 上有一个来自 Microsoft 的服务虚拟化工具,称为托管服务引擎,旨在将客户端与 Web 服务实现分离。它可能会满足您的需求或为您提供良好的开端。我没有真正深入研究它,只是浏览了MSDN中的一篇文章,你的描述让我想起了它。

于 2009-05-29T03:17:34.227 回答