Hi all,

I am trying to implement a web service client that can send soap request with plain xml string to a web service with WS-Security and apply WS-Policy to client at runtime. From what I read,
using Dispatcher with interceptor (which loads WS-Policy) is the way to go.

Just to show I have done my home work:

* This thread http://cxf.547215.n5.nabble.com/Dynamicall-y-define-WS-Policy-in-CXF-td5713085.html outlines the interceptor approach to load WS-Policy

* This thread http://cxf.547215.n5.nabble.com/adding-interceptors-to-a-dynamic-jax-ws-dispatcher-client-td5723001.html seems to confirm interceptor can be dynamically added to a Dispatcher client

* So I look for sample code of using Dispatcher and find /apache-cxf-2.7.6-src/distribution/src/main/release/samples/in_jvm_transport/src/main/java/demo/colocated/client/DispatchSourceClient.java. Got it to work by sending plain text request to the sample DoubleIt web service without any ws-policy.

* Then it dawned on me that I have no idea how the imported WS-Policy can be applied to a WSDL that has no WS-Policy, after some googling, I believe the imported WSDL needs to have format specified in http://www.w3.org/Submission/WS-PolicyAttachment/

* Next question that came up is how to apply config of encryption & signing dynamically at runtime. Since it needs to be dynamic, I ruled out using Spring XML config. After some googling, I found this excellent blog http://ashakirin.blogspot.co.nz/2013/04/cxf-security-getting-certificates-from.html which shows Crypto provider object can be programmatically
  set in interceptor, i.e.

          public class CustomSecurityInterceptor extends
   AbstractPhaseInterceptor<Message> {
            public CustomSecurityInterceptor () {
            super(Phase.PRE_LOGICAL);
            }

            @Override
            public void handleMessage(Message message) throws Fault {
               PKICryptoProvider pkiCryptoProvider = new
   PKICryptoProvider();

               message.put(SecurityConstants.ENCRYPTION_CRYPTO,
   pkiCryptoProvider);
               message.put(SecurityConstants.SIGNATURE_CRYPTO,
   pkiCryptoProvider);
        }

I am assuming this can provide the missing link of configuring keystore config at runtime. Correct me if wrong.

Right now, my half baked non-working prototype interceptor is

   import ...
   public class DynamicWSPolicyOutInterceptor extends
   AbstractPolicyInterceptor {

        public DynamicWSPolicyOutInterceptor() {
            super(
   InterceptorIdConstants.DYNAMIC_WS_POLICY_OUT_INTERCEPTOR_ID,
   Phase.SETUP);
            getBefore().add( PolicyOutInterceptor.class.getName()  );
        }

        @Override
        protected void handle(Message message) throws PolicyException {
            try {

              // this will get test WS-Policy data
             PolicyUtil policyUtil = new PolicyUtil();

                // 1. Build effective policy for response
                PolicyBuilder builder =
   message.getExchange().getBus().getExtension(PolicyBuilder.class);
                Policy effectivePolicy = builder.getPolicy(
   policyUtil.getTestPolicyData() ) ;

                // 2. Apply effective policy
                message.put( PolicyConstants.POLICY_OVERRIDE,
   effectivePolicy );

              // 3. Apply keystore config like
   
http://ashakirin.blogspot.co.nz/2013/04/cxf-security-getting-certificates-from.html
              // TODO!!

            } catch (Exception e) {
                throw new PolicyException( e );
                e.printStackTrace();
                // logging latter
            }
        }
   }


Now the working PolicyUtil is:

   import ...
   import org.apache.cxf.helpers.IOUtils;
   public class PolicyUtil {

          // load test data policy file
         private InputStream in =
   this.getClass().getResourceAsStream("/ws_policy/ws_policy_1");

          InputStream getTestPolicyData() {
               return in;
         }

         public static void main(String args[]) throws Exception {

            PolicyUtil policyUtil = new PolicyUtil();
            String wsPolicy =
   IOUtils.toString(policyUtil.getTestPolicyData(), "UTF-8");
            System.out.println( wsPolicy ); // OK
        }
   }


As you can see, it's like playing a painful jig-saw puzzle, so my ultimate question is, has anyone done something this like already and care to share sample code?
This can save me  or anyone else a lot of pain. :)

If sample code is not possible, then can you at least confirm if I am still in the right direction and if there is still any road blocks I haven't hit my head into the wall yet?

Thanks

Regards,
Sam

Reply via email to