Question

I am writing a Java web services client using Metro/WSIT libraries, and the web services I need to hit are WCF services. (I have little to no control over the service-side and the WSDLs.)

The web services are secured with both transport-level security (SSL) and a federated security model with a Security Token Service (WS-Trust/WS-Security). I have implemented clients in .NET easily using the Windows Identity Foundation, issuing a Security Token first and then using the (CreateChannelWithIssuedToken) method to make requests to other web services.

I am having difficulty mimicing this behavior in Java, though, using Metro/WSIT. It is my understanding that due to the lack of WS-Policy information in the WSDL, WSIT will not enable security processing for communications with the service. I have done this manually in making requests by manipulating the SOAP request headers before it is sent, and I am now receiving messages identical to what I would receive on the .NET client side.

Now, my problem is that I am getting the following error:

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)

because the SOAP response has a Security section in the 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>
    ...

Given that I can't modify the WSDL, is there a way I can manually force Metro/WSIT to enable security processing for the response so this exception is not thrown? I don't intend to use the security headers, and the payload of the response is as expected. I understand what I am seeing is the correct behavior if the client doesn't understand a header with mustunderstand="1", but I am looking for a way to suppress this exception.

I have read other questions, such as this one, that seem to be close to what I want but I have not found an answer yet. Any advice/solutions/etc. are greatly appreciated!

Was it helpful?

Solution

I found a workaround (suitable for the time being) involving a custom "tube" inserted into the Metro processing pipeline.

I created a custom processing tube class that extends com.sun.xml.ws.api.pipe.helper.AbstractFilterTubeImpl, and overrides processResponse( Packet packet ), searching for headers with the name "Security" and calling packet.getMessage().getHeaders().understood( int ) for the index in the header list of the security header I found. This prevents processing down the tube from trying to understand the security headers (since the problem is that it doesn't).

After this I created a tube factory (implementing com.sun.xml.ws.assembler.TubeFactory) for my custom tube.

I then copied the contents of webservices-rt.jar/META-INF/metro-default.xml to META-INF/metro.xml in my project, and added a <tube-factory> element for my factory class; under <client-side> I put it just above the transport tube factory, and under <endpoint-side> I put it at the top of the list, above the transport tube factory.

Hopefully this helps anybody with a similar problem. Being able to add custom processing to the Metro pipeline seems immensely powerful but also dangerous; YMMV.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top