java - WSIT 在使用自定义安全 header 请求后不理解 SOAP 安全 header

标签 java soap wsit wcf-interoperability

我正在使用 Metro/WSIT 库编写 Java Web 服务客户端,我需要访问的 Web 服务是 WCF 服务。 (我几乎无法控制服务端和 WSDL。)

Web 服务受到传输级安全性 (SSL) 和具有安全 token 服务 (WS-Trust/WS-Security) 的联合安全模型的保护。我已经使用 Windows Identity Foundation 在 .NET 中轻松实现了客户端,首先发出安全 token ,然后使用 ( CreateChannelWithIssuedToken ) 方法向其他 Web 服务发出请求。

不过,使用 Metro/WSIT,我很难在 Java 中模仿这种行为。据我了解,由于 WSDL 中缺少 WS-Policy 信息,WSIT 将不会为与服务的通信启用安全处理。我在发送请求之前通过操纵 SOAP 请求 header 手动完成了此操作,现在我收到的消息与我在 .NET 客户端收到的消息相同。

现在,我的问题是出现以下错误:

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood
at com.sun.xml.ws.protocol.soap.MUTube.createMUSOAPFaultException(MUTube.java:148)
at com.sun.xml.ws.protocol.soap.ClientMUTube.processResponse(ClientMUTube.java:96)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:972)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
at com.sun.xml.ws.client.Stub.process(Stub.java:429)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:168)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:102)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:151)

因为 SOAP 响应在 header 中有一个安全部分:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <u:Timestamp u:Id="_0">
            <u:Created>2012-05-14T21:20:08.782Z</u:Created>
            <u:Expires>2012-05-14T21:25:08.782Z</u:Expires>
        </u:Timestamp>
    </o:Security>
</s:Header>
<s:Body>
    ...

鉴于我无法修改 WSDL,有没有一种方法可以手动强制 Metro/WSIT 为响应启用安全处理,从而不会引发此异常?我不打算使用安全 header ,并且响应的有效负载符合预期。我知道如果客户端不理解带有 mustunderstand="1"的 header ,我所看到的是正确的行为,但我正在寻找一种方法来抑制此异常。

我已经阅读了其他问题,例如this one ,这似乎接近我想要的,但我还没有找到答案。任何建议/解决方案/等。非常感谢!

最佳答案

我找到了一个解决方法(暂时适用),涉及将自定义“管”插入到 Metro 处理管道中。

我创建了一个扩展 com.sun.xml.ws.api.pipe.helper.AbstractFilterTubeImpl 的自定义处理管类, 并覆盖 processResponse( Packet packet ) ,搜索名为“Security”的 header 并调用 packet.getMessage().getHeaders().understood( int )对于我找到的安全 header 的 header 列表中的索引。这可以防止向下处理试图理解安全 header (因为问题是它不理解)。

在此之后,我为我的定制管创建了一个管工厂(实现 com.sun.xml.ws.assembler.TubeFactory)。

然后我将 webservices-rt.jar/META-INF/metro-default.xml 的内容复制到我项目中的 META-INF/metro.xml,并添加了一个 <tube-factory>我的工厂类的元素;在 <client-side> 下我把它放在运输管工厂的正上方,在 <endpoint-side> 下面我把它放在列表的顶部,在运输管工厂的上方。

希望这对遇到类似问题的人有所帮助。能够向 Metro 管道添加自定义处理似乎非常强大,但也很危险; YMMV.

关于java - WSIT 在使用自定义安全 header 请求后不理解 SOAP 安全 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10591777/

相关文章:

java - Kafka Producer NetworkException 和超时异常

java - 如果用户输入String而不是Int,有什么可能的异常(exception)情况?

java - 无法通过 Java 发送电子邮件

.net - 如何使用 WCF 跟踪查看器查看在线发送的原始 SOAP 信息?

java - 使用 SSL 的 Metro Web 服务 - 这是一个安全的对话吗

java - Java 中可撤消的文本区域

web-services - 在没有 wsdl 的情况下在soapUI 中创建 MockService

java - 如何从 SOAP 主体获取子元素?

java - WSIT:JKS 相对文件路径

java - 您可以通过编程方式更改 SecurityTokenService 的 AlgorithmSuite 吗?