4 Replies Latest reply on Jan 24, 2008 6:46 AM by cavani

    Dispatch WS-Security Bug

    cavani

      I was trying to use WS-Security with JAX-WS Dispatch from version 2.0.2 but the response message returned still encrypted (it works with generated client). After some debug and code reading, I think that I figured it out.

      On DispatchImpl, the code is:

      (...) msgContext.put(MessageContextJAXWS.MESSAGE_OUTBOUND_PROPERTY, Boolean.TRUE);
      
       QName portName = epMetaData.getPortName();
       try
       {
       // Call the request handlers
       boolean handlerPass = callRequestHandlerChain(portName, handlerType[0]);
       handlerPass = handlerPass && callRequestHandlerChain(portName, handlerType[1]);
       handlerPass = handlerPass && callRequestHandlerChain(portName, handlerType[2]);
      
       // Handlers might have replaced the message
       reqMsg = (SOAPMessageImpl)msgContext.getSOAPMessage();
      
       MessageAbstraction resMsg = null;
       if (handlerPass)
       {
       Map<String, Object> callProps = new HashMap<String, Object>(getRequestContext());
       EndpointInfo epInfo = new EndpointInfo(epMetaData, targetAddress, callProps);
       resMsg = getRemotingConnection().invoke(reqMsg, epInfo, false);
      
       // Call the response handler chain, removing the fault type entry will not call handleFault for that chain
       handlerPass = callResponseHandlerChain(portName, handlerType[2]);
       faultType[2] = null;
       handlerPass = handlerPass && callResponseHandlerChain(portName, handlerType[1]);
       faultType[1] = null;
       handlerPass = handlerPass && callResponseHandlerChain(portName, handlerType[0]);
       faultType[0] = null;
       }
      (...)
      


      But on CommonClient / ClientImpl, the similar code block is a bit different, but, essentially, the direction change after invocation.

      (...)
       DirectionHolder direction = new DirectionHolder(Direction.OutBound);
      
       // Get the order of pre/post handlerchains
       HandlerType[] handlerType = new HandlerType[] { HandlerType.PRE, HandlerType.ENDPOINT, HandlerType.POST };
       HandlerType[] faultType = new HandlerType[] { HandlerType.PRE, HandlerType.ENDPOINT, HandlerType.POST };
      
       QName portName = epMetaData.getPortName();
       try
       {
       // Get the binding from the provider
       CommonBinding binding = (CommonBinding)getCommonBindingProvider().getCommonBinding();
       binding.setHeaderSource(this);
      
       // Create the invocation and sync the input parameters
       epInv = new EndpointInvocation(opMetaData);
       epInv.initInputParams(inputParams);
      
       // Set the required outbound properties
       setOutboundContextProperties();
      
       // Bind the request message
       MessageAbstraction reqMessage = binding.bindRequestMessage(opMetaData, epInv, unboundHeaders);
      
       // Add possible attachment parts
       addAttachmentParts(reqMessage);
      
       // Call the request handlers
       boolean handlerPass = callRequestHandlerChain(portName, handlerType[0]);
       handlerPass = handlerPass && callRequestHandlerChain(portName, handlerType[1]);
       handlerPass = handlerPass && callRequestHandlerChain(portName, handlerType[2]);
      
       // Handlers might have replaced the message
       reqMessage = msgContext.getMessageAbstraction();
      
       if (handlerPass)
       {
       String targetAddress = getTargetEndpointAddress();
      
       // Fall back to wsa:To
       AddressingProperties addrProps = (AddressingProperties)msgContext.get(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_OUTBOUND);
       if (targetAddress == null && addrProps != null && addrProps.getTo() != null)
       {
       AddressingConstantsImpl ADDR = new AddressingConstantsImpl();
       String wsaTo = addrProps.getTo().getURI().toString();
       if (wsaTo.equals(ADDR.getAnonymousURI()) == false)
       {
       try
       {
       URL wsaToURL = new URL(wsaTo);
       log.debug("Sending request to addressing destination: " + wsaToURL);
       targetAddress = wsaToURL.toExternalForm();
       }
       catch (MalformedURLException ex)
       {
       log.debug("Not a valid URL: " + wsaTo);
       }
       }
       }
      
       // The endpoint address must be known beyond this point
       if (targetAddress == null)
       throw new WSException("Target endpoint address not set");
      
       Map<String, Object> callProps = new HashMap<String, Object>(getRequestContext());
       EndpointInfo epInfo = new EndpointInfo(epMetaData, targetAddress, callProps);
       if (shouldMaintainSession())
       addSessionInfo(reqMessage, callProps);
      
       SOAPRemotingConnection remotingConnection = new SOAPRemotingConnection();
       MessageAbstraction resMessage = remotingConnection.invoke(reqMessage, epInfo, oneway);
      
       if (shouldMaintainSession())
       saveSessionInfo(callProps, getRequestContext());
      
       // At pivot the message context might be replaced
       msgContext = processPivotInternal(msgContext, direction);
      
       // Copy the remoting meta data
       msgContext.put(CommonMessageContext.REMOTING_METADATA, callProps);
      
       // Associate response message with message context
       msgContext.setMessageAbstraction(resMessage);
       }
      
       setInboundContextProperties();
      
       // Get the return object
       Object retObj = null;
       if (oneway == false && handlerPass)
       {
       // Verify
       if (binding instanceof CommonSOAPBinding)
       ((CommonSOAPBinding)binding).checkMustUnderstand(opMetaData);
      
       // Call the response handler chain, removing the fault type entry will not call handleFault for that chain
       handlerPass = callResponseHandlerChain(portName, handlerType[2]);
       faultType[2] = null;
      (...)
      


      This is a bug, right? (sorry if I am wrong)

      If so, this can be fixed fro 2.0.3 still?

      Thanks,

        • 1. Re: Dispatch WS-Security Bug
          cavani

          Further exploration and minimal code change seems to fix this issue:

          First, changing direction (pivotation) from out- to in-bound.

          (...)
           resMsg = getRemotingConnection().invoke(reqMsg, epInfo, false);
          
           msgContext = MessageContextJAXWS.processPivot(msgContext);
           msgContext.setMessageAbstraction(resMsg);
          
           // Call the response handler chain, removing the fault type entry will not call handleFault for that chain
           handlerPass = callResponseHandlerChain(portName, handlerType[2]);
          (...)
          


          With this, WS-Security Handler is called to decrypt the response message, but it result in an NPE.

          In class WSSecurityDispatcher, method handleInbound, I change string definition with null test.

          (...)
           OperationMetaData opMetaData = ctx.getOperationMetaData();
           if (opMetaData == null)
           {
           // Get the operation meta data from the soap message
           // for the server side inbound message.
           EndpointMetaData epMetaData = ctx.getEndpointMetaData();
           opMetaData = soapMessage.getOperationMetaData(epMetaData);
           }
          
           String operation = opMetaData == null ? null : opMetaData.getQName().toString();
           String port = opMetaData == null ? null : opMetaData.getEndpointMetaData().getPortName().getLocalPart();
          
           List<OperationDescription<RequireOperation>> operations = buildRequireOperations(config, operation, port);
          (...)
          


          It is working now, but I don't have sure if this is all, but it is almost good (I really like upstream fix).

          Thanks,

          • 2. Re: Dispatch WS-Security Bug
            cavani
            • 3. Re: Dispatch WS-Security Bug
              asoldano

              Thank you for debugging this, I'll take a look at it for the 2.0.4.GA release (unfortunately it's too late for 2.0.3).

              • 4. Re: Dispatch WS-Security Bug
                cavani

                I am pleased to help.

                I will test more, but will wait for that version.

                Thanks,