在使用自定义安全标头的请求之后,WSIT无法理解SOAP安全标头

时间:2012-05-14 22:14:12

标签: java soap wsit wcf-interoperability

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

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

但是,使用Metro / WSIT,我很难在Java中模仿这种行为。据我了解,由于WSDL中缺少WS-Policy信息,WSIT不会启用与服务通信的安全处理。我通过在发送之前操纵SOAP请求标头来手动完成请求,现在我收到的消息与我在.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响应在标题中有一个Security部分:

<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为响应启用安全处理,这样就不会抛出这个异常?我不打算使用安全标头,响应的有效负载是预期的。我理解我所看到的是正确的行为,如果客户端不理解带有mustunderstand =“1”的标题,但我正在寻找一种方法来抑制此异常。

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

1 个答案:

答案 0 :(得分:3)

我找到了一种解决方法(暂时适用),其中包含一个插入Metro处理管道的自定义“管”。

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

在此之后,我为自定义管创建了一个管工厂(实施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。