Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-7650

CXF WS-Provider returns http 200 although an error occurred

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 3.2.2
    • None
    • Core
    • Unknown
    • Patch

    Description

      Hi,

      I am faced with the issue, that a CXF WS-Provider returns a http 200, although an error within the WS-Provider occurred.

      ###########################################
      Error within the WS-Provider

      [ qtp1256350655-27] PhaseInterceptorChain DEBUG Invoking handleFault on interceptor org.apache.cxf.ws.policy.ServerPolicyOutFaultInterceptor@53236355
      [ qtp1256350655-27] PhaseInterceptorChain WARN Application {http://cxf.apache.org/hello_world_soap_http}GreeterService#{http://cxf.apache.org/hello_world_soap_http}greetMe has thrown exception, unwinding now
      org.apache.cxf.interceptor.Fault: No configured signature username detected
      at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:237)
      at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.handleBinding(AsymmetricBindingHandler.java:117)
      at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessageInternal(PolicyBasedWSS4JOutInterceptor.java:185)
      at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:109)
      at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:96)
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
      at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
      at org.apache.cxf.phase.PhaseInterceptorChain.wrapExceptionAsFault(PhaseInterceptorChain.java:374)
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:332)
      at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
      at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
      at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:247)
      at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:79)
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
      at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
      at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
      at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:170)
      at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
      at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219)
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
      at org.eclipse.jetty.server.Server.handle(Server.java:530)
      at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347)
      at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256)
      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
      at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
      at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247)
      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140)
      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
      at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382)
      at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:708)
      at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:626)
      at java.lang.Thread.run(Thread.java:748)
      Caused by: org.apache.cxf.ws.policy.PolicyException: No configured signature username detected
      at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractCommonBindingHandler.unassertPolicy(AbstractCommonBindingHandler.java:92)
      at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getSignatureBuilder(AbstractBindingBuilder.java:1863)
      at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignature(AsymmetricBindingHandler.java:721)
      at org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:193)
      ... 33 more
      [ qtp1256350655-27] AbstractHTTPDestination DEBUG Finished servicing http request on thread: Thread[qtp1256350655-27,5,main]

      ##################################################
      Response within the WS-Consumer
      [ main] Greeter INFO Inbound Message
      ----------------------------
      ID: 1
      Response-Code: 200
      Encoding: ISO-8859-1
      Content-Type:
      Headers: {Date=[Wed, 10 Jan 2018 15:12:24 GMT], Server=[Jetty(9.4.8.v20171121)], transfer-encoding=[chunked]}
      --------------------------------------
      [ main] PhaseInterceptorChain DEBUG Invoking handleMessage on interceptor org.apache.cxf.interceptor.AttachmentInInterceptor@2bb1d0aa

       

       

      As you can see, the http response code is 200 and no body is set. The expected response code is http 500.

      I attached a patch, which will fix following issues:

      1st issue: Message Exchange Pattern (MEP) is request response. I setup a Camel Route with a CXF Endpoint as WS-Provider.
      I configured WSS (only signing) but NO signature user within the cxf endpoint. In case a error occurs within the Camel Route,
      above mentioned http 200 code will be returned to the WS-Consumer.

      Root cause is, that in class PhaseInterceptorChain.java following code snippet handles the exception of the Camel Route:
      } catch (RuntimeException ex) {
      if (!faultOccurred)

      { faultOccurred = true; wrapExceptionAsFault(message, ex); }

      state = State.ABORTED;
      }

      The method wrapExceptionAsFault handles the unwinding and calls faultObserver.onMessage(message);

      When now a second RuntimeException is thrown, e.g. in one of the OutInterceptors (in my case in the PolicyBasedWSS4JOutInterceptorInternal), this exception disturbs
      the fault handling and a http 200 without a payload is returned to the WS-Consumer.

      2nd issue: MEP is oneway. I am configuring a Onewway WS-Provider within the Camel Route. Again with WSS (only signing) and I am not setting a signature
      user (is not necessary, as there is no response to sign). In addition I set the property org.apache.cxf.oneway.robust to true. With this setting
      errors of the Camel Route should be propagated back to the WS-Consumer.
      In my setup again a http 200 is returned to the WS_Consumer, although a error occurred in the Camel Route and the robust mode is activated.
      This is caused by the second exception in the fault handling because of the missing signature user within the configuration. I am not sure, whether the
      fault message should be signed in this case, but nevertheless the return code should be 500 and not 200.
      Your thoughts are welcome.

       

      Regarding my patch:

      My focus was to return at least a http 500, instead of 200. Therefore I had to modify the PhaseInterceptorChain.java and the fault observer
      implementation to detect, whether a second exception occurs in the fault handling.

      Another option would be to modify (in this case with WSS) the fault handling method implementation of the OutInterceptor PolicyBasedWSS4JOutInterceptorInternal.
      This method is called via the method wrapExceptionAsFault, when the unwinding is done.

      What is your opinion?

      Best regards
      Kai

      Attachments

        Activity

          People

            Unassigned Unassigned
            kairo Kai Rommel
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated: