JAX-WS Metro,如何拦截具有无效字符/签名不匹配的正确 encrypted/signed 消息

JAX-WS Metro, how to intercept correct encrypted/signed message with invalid characters / signature mismatch

我的问题与this one

很相关

我花了数周的时间来尝试解决这个问题,但似乎没有值得一提的解决方案,除了上述问题的解决方案,这是一个糟糕的解决方法,但似乎确实存在周围别无他物。

我们正在尝试与具有已建立的 运行 Web 服务的遗留系统进行通信,并在其 WSDL 中声明了某些 WS-Security 约束。我们无法更改服务器上的任何内容,我们只能按照它的指示去做。我们还有一个第三方客户端实现,它实际工作并与服务器通信,所以我们知道通信有效——使用那个特定的客户端。现在,我们想自己做。

上述 WS-Security 策略包括加密和签名。有以下操作场景:

第二个选项当然是我们尝试做的。然后我们分支如下:

网络上的每个人都建议后一种选择(我也尝试过) - 但暂时我选择了第一种(特别是因为我们没有与 Spring 进行任何集成以利用CXF与其很好的结合)

在与一些模棱两可的文档和各种向导 (NetBeans) 作斗争之后,我们找到了一个解决方案,其中包含很少的自定义代码、一个包含一些密钥库的配置文件,以及通常从 wsimport 实用程序生成的代码。

一段时间过去了,它包括转储 XML SOAP 请求和响应,将我们生成的失败请求和来自第 3 方客户端的成功请求和响应进行比较。很痛苦,没有结果——消息各不相同,但核心逻辑和结构没问题——然后——你实际上无法比较加密部分。一段时间后,我最终得到了一个客户端,它发送了一些东西,实际上收到了一些东西,但未能解密响应。

其实解密没问题,只是签名摘要验证失败。值得一提的是,原始 XML 消息包含一个“&”字符,以及多个换行符。 IE。 SOAP 消息的负载在语法上不正确 XML。不管怎样

似乎这个摘要验证深深植根于 Metro/WSIT 堆栈中,我绝对没有办法真正拦截和更正该摘要 - 或者实际上是计算该摘要的内容 - 显然- 问题是一些特殊字符在摘要计算之后或之前被翻译或规范化,而我们(而不是我试图用来保持双手清洁的底层实现)做了一些与 Web 服务的服务器端不同的事情做了。

甚至是地铁(好听的名字,但非常稀缺的文档 - 这些天似乎没有人使用 Metro/WSIT - 或者,我应该说,没有人使用 SOAP,或具有这种安全级别的 SOAP? -当我尝试 Apache CXF 时,生成的 SOAP 消息看似相似)并且它们拦截消息的方式似乎没有帮助 - 在尝试获取消息的原始内容时,没有提供方法(Packet.getMessage(). writeTo... - 和其他变体)实际上可以绕过摘要验证 - 因为他们都试图以 StAX 方式读取内容,流式传输等(调用 StreamingPayLoadDigester.accept 总是失败)

但希望最后会破灭,我会一次又一次地尝试寻找一些晦涩的未记录的魔法来让我的东西发挥作用。好吧,我正要结束它并努力研究 java 加密 - 直到我发现上述问题,就是这样。实际上它 "exploits" 从 Metro 代码深处打印的日志消息(我认为实际上是从 wssx-impl)和规范化的解密消息,在抛出摘要不匹配异常之前。值得庆幸的是,此消息是使用 java.util.logging 打印的,并且可以通过多种方式拦截它 - 例如将它发送到某种同步队列中,供我的客户使用。啊。如果有人有更好的想法,请写下您的想法。

谢谢大家

最后我求助于重建在 GitHub 上找到的 Metro/WSIT 版本 2.1.1,在 WS-SX 实施项目中评论了一行 (ws-sx\wssx-impl...\StreamingPayloadDigester.java:145)

if (!Arrays.equals(originalDigest, calculatedDigest)) {
    XMLSignatureException xe = new XMLSignatureException(LogStringsMessages.WSS_1717_ERROR_PAYLOAD_VERIFICATION());
    logger.log(Level.WARNING, LogStringsMessages.WSS_1717_ERROR_PAYLOAD_VERIFICATION()); //,xe);
    // bypass throwing exception
    // throw new WebServiceException(xe);
}

本来可以用更好的方式来完成,例如引入一个标志。

项目的顺序,从我进行更改的最小项目开始,到我作为 Metro 实施包含在我自己的项目中的项目,大致如下:

  1. 在 ->
  2. 中引用了 WS-SX 实现
  3. 在 ->
  4. 中引用了 WS-Security 项目
  5. Metro Web 服务互操作性技术实施包 (wsit-impl) 在 ->
  6. 中被引用
  7. 我的客户端中包含 Metro Web Serrvices Runtime non-OSGi Bundle (webservices-rt)