从 Java 调用 .NET Web Service (WSE 2/3, WS-Security)

2022-09-01 23:32:10

我需要从Java调用用.NET编写的Web服务。Web 服务实现了 WS-Security 堆栈(WSE 2 或 WSE 3,从我掌握的信息中看不出来)。

我从服务提供商处收到的信息包括 WSDL、policyCache.config 文件、一些示例 C# 代码以及可以成功调用该服务的示例应用程序。

这并不像听起来那么有用,因为不清楚我应该如何使用这些信息来编写Java客户端。如果未根据策略对 Web 服务请求进行签名,则该请求将被服务拒绝。我正在尝试使用Apache Axis2,但我找不到任何关于我应该如何使用policyCahce.config文件和WSDL来生成客户端的说明。

我在 Web 上找到了几个例子,但在所有情况下,这些例子的作者都控制了服务和客户端,因此能够在两端进行调整,以便使其正常工作。我不在那个位置。

有没有人成功地做到这一点?


答案 1

WS-Security 规范通常不包含在 WSDL 中(从不包含在 WSE WSDL 中)。因此,wsdl2java甚至不知道此服务甚至需要WS-Security。WSE WSDL 中不存在安全约束这一事实令我大失所望(WCF 将在 WSDL 中包含 WS-Trust 信息)。

在客户端,需要使用 Rampart 将必要的 WS-Security 标头添加到传出客户端消息中。由于 WSDL 不报告哪些 WS-Security 设置是必需的,因此最好通过询问服务提供商需要什么来获得最佳效果。WS-Security 要求可能是简单的纯文本密码,也可能是 X509 证书,也可能是加密消息.....Rampart 应该能够处理大多数这些方案。

Apache Rampart 通过在您的 axis2.xml 文件中接合模块来“打开”。您需要下载 Rampart 模块并将其放在 axis2 目录中的特定位置,然后修改 xml 文件。您也可以以程序方式参与Rampart(如果这是一项要求,请编辑您的原始问题,我将编辑此回复)。

根据您配置 rampart 的方式(通过其他 XML 文件或以编程方式),它将截获任何传出消息并向其添加必要的 WS-Security 信息。我个人使用带有rampart的axis2来调用WSE3服务,该服务以明文形式使用UsernameToken进行保护,并且效果很好。类似但更高级的方案也应该有效。在上面链接的站点上,有关于如何设置和开始使用Rampart的更多详细信息。如果您对Rampart的细节或如何在特定的WSE设置中使用Rampart有疑问,请编辑您的问题,我会尽力回答。


答案 2

这似乎是一个流行的问题,所以我将概述我们在这种情况下所做的工作。

似乎.NET中内置的服务遵循较旧的ws寻址标准(http://schemas.xmlsoap.org/ws/2004/03/addressing/),而axis2只理解较新的标准(http://schemas.xmlsoap.org/ws/2004/08/addressing/)。

此外,提供的 policyCache.config 文件采用 axis2 rampart 模块无法理解的形式。

因此,我们必须执行的步骤,简而言之:

  • 阅读 policyCache.config 并尝试理解它。然后将其重写为Rampart可以理解的策略。(一些更新的文档有所帮助。
  • 使用此策略配置城墙。
  • 获取 .pfx 文件中提供的密钥,并将其转换为 Java 密钥存储。Jetty附带了一个实用程序,可以做到这一点。
  • 使用该密钥存储配置城墙。
  • 编写一个自定义 axis2 处理程序,该处理程序将来自 axis2 的较新的 ws 寻址内容向后转换为服务预期的较旧内容。
  • 将 axis2 配置为对传出消息使用处理程序。

最后,它需要大量的配置和代码,这些配置和代码应该是供应商支持的开放标准。

虽然我不确定替代方案是什么...你能等待供应商(或者在这种情况下,一个供应商)确保一切都会相互操作吗?

作为后记,我要补充一点,我最终没有做这项工作,这是我团队中的其他人,但我认为我得到了正确的突出细节。我正在考虑的另一个选项(在我的队友接手之前)是直接调用 WSS4J API 来构造 SOAP 信封,正如 .NET 服务所期望的那样。我认为这也会奏效。


推荐