You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Sam <j2...@gmail.com> on 2013/11/03 12:38:24 UTC

Re: Dynamically define WS-Policy for web service client by using Dispatcher and interceptor

Hi Andrei or anyone else,

When I try to implement external WS-Policy file that can be applied to a 
WSDL, I came across this link 
http://cxf.apache.org/docs/how-it-works.html which says
wsp:PolicyAttachment can be used to do that BUT it also says "It is not 
possible however to associate a Policy with an operation or a message 
this way".

Does that mean it's not possible to achieve something like the following 
with ws:PolicyAttachment right now?

                 ...
                 <wsdl:binding name="DoubleItBinding"
        type="tns:DoubleItPortType">

                       <wsp:PolicyReference
        URI="#DoubleItUTSymmetricX509Policy"/>

                       <soap:binding style="document"
                      transport="http://schemas.xmlsoap.org/soap/http" />

                       <wsdl:operation name="DoubleIt">
                      <soap:operation soapAction=""/>

                      <wsdl:input>
                          <soap:body use="literal"/>
                         <wsp:PolicyReference
        URI="#DoubleItBinding_DoubleIt_Input_Policy"/>
                      </wsdl:input>

                      <wsdl:output>
                         <soap:body use="literal"/>
                         <wsp:PolicyReference
        URI="#DoubleItBinding_DoubleIt_Output_Policy"/>
                      </wsdl:output>
                       </wsdl:operation>

                  </wsdl:binding>

                  ...

                  <wsp:Policy wsu:Id="DoubleItUTSymmetricX509Policy">
                     ....
                  </wsp:Policy>

                  <wsp:Policy
        wsu:Id="DoubleItBinding_DoubleIt_Input_Policy">
                     ....
                  </wsp:Policy>

                  <wsp:Policy
        wsu:Id="DoubleItBinding_DoubleIt_Output_Policy">
                     ....
                  </wsp:Policy>
                 .....


     * Does it make sense to use wsa:Action within ws:PolicyAttachment 
to associate WS-Policy with wsdl:input, wsdl:output and wsdl:binding to 
achieve similar thing as above
        without WSDL being aware this?

        i.e.

         <!-- this is adapted from 
/apache-cxf-2.7.6-src/distribution/src/main/release/samples/ws_policy/src/main/resources/addr-external.xml 
-->
         <attachments xmlns:wsp="http://www.w3.org/ns/ws-policy" 
xmlns:wsa="http://www.w3.org/2005/08/addressing">
                 <wsp:PolicyAttachment>

                     <wsp:AppliesTo>
                         <wsa:EndpointReference>

                         <!-- Can we use IRI/URI that represents
    wsdl:input, wsdl:output and wsdl:binding of wsa:Action here??? -->
    <wsa:Address>http://localhost:9000/SoapContext/SoapPort</wsa:Address>

                         </wsa:EndpointReference>
                     </wsp:AppliesTo>

                 <wsp:Policy>
                     <wsam:Addressing 
xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                     <wsp:Policy/>
                     </wsam:Addressing>
                 </wsp:Policy>

                  <wsp:Policy>
                     ....
                 </wsp:Policy>

                  ...

                 </wsp:PolicyAttachment>
              </attachments>

     The link http://cxf.apache.org/docs/how-it-works.html seems to 
suggest implementing DomainExpressionBuilder interface which seems a bit 
heavy.

     Does anyone have best practice advice on how to apply external 
WS-Policy file to WSDL like above? Or maybe my approach is totally 
wrong. I can't seem to find existing example
     in CXF source that does this.

     Thanks,
     Sam


On 31/10/2013 4:10 a.m., Andrei Shakirin wrote:
> Hi,
>
> The preparation of the sample code will take a bit time.
> Meanwhile you use:
> - the blog http://ashakirin.blogspot.de/2012/02/using-ws-policy-in-cxf-projects.html to dynamically set policy and XKMS crypto implementation
> - and XKMS crypto implementation https://svn.apache.org/repos/asf/cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/XkmsCryptoProvider.java as basis for your custom crypto.
>
> Regards,
> Andrei.
>
>> -----Original Message-----
>> From: Sam [mailto:j2eedodo@gmail.com]
>> Sent: Dienstag, 29. Oktober 2013 09:51
>> To: users@cxf.apache.org
>> Subject: Re: Dynamically define WS-Policy for web service client by using
>> Dispatcher and interceptor
>>
>> Hi Andrei,
>>
>> Sample code in GitHub will be great. My scenario is to have dynamic policy
>> changes and keystore config. Static Dispatch client is simply not that
>> impressive.
>>
>> Thanks,
>> Sam
>>
>> On 29/10/2013 3:21 a.m., Andrei Shakirin wrote:
>>> Hi,
>>>
>>> 1. Applying WS-Policy to Dispatcher client dynamically.
>>>       The question is it really required in your scenario that Dispatcher client
>> should dynamically react on policy changes between the calls.
>>>       If no, you could try to avoid setting policy via interceptor through
>> POLICY_OVERRIDE  message property
>> (http://cxf.547215.n5.nabble.com/Dynamicall-y-define-WS-Policy-in-CXF-
>> td5713085.html). It will be enough to set policy in the Dispatch client
>> statically.
>>>       If yes, than own interceptor and POLICY_OVERRIDE message property
>> will be only the solution.
>>> 2. Config of encryption & signing dynamically at runtime
>>>       Yes, doing that through Crypto provider is a right way, you can also look
>> how it is implemented in XKMS service
>> (https://svn.apache.org/repos/asf/cxf/trunk/services/xkms/xkms-
>> client/src/main/java/org/apache/cxf/xkms/crypto/impl/XkmsCryptoProvider
>> .java ) and considerate to reuse XKMS service
>> (http://ashakirin.blogspot.de/2013/04/cxf-security-getting-certificates-
>> from.html).
>>> Both solutions dynamic policy mechanism and custom crypto provider are
>> working in some projects I was involved.
>>> If you like, I could distil the code, publish it on the GitHub and reference
>> from my blog.
>>> Regards,
>>> Andrei.
>>>
>>>
>>>> -----Original Message-----
>>>> From: Sam [mailto:j2eedodo@gmail.com]
>>>> Sent: Sonntag, 27. Oktober 2013 13:40
>>>> To: users@cxf.apache.org
>>>> Subject: Dynamically define WS-Policy for web service client by using
>>>> Dispatcher and interceptor
>>>>
>>>> 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/j
>>>> ava/ 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-certific
>>>> ates-
>>>> 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-certific
>>>> ates-
>>>> 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


Re: Dynamically define WS-Policy for web service client by using Dispatcher and interceptor

Posted by Sam <j2...@gmail.com>.
Cool!! Thanks Andrei.

Regards,
Sam

On 4/11/2013 10:47 p.m., Andrei Shakirin wrote:
> Hi,
>
>> From: Sam [mailto:j2eedodo@gmail.com]
>> Sent: Sonntag, 3. November 2013 12:38
>> To: Andrei Shakirin
>> Cc: users@cxf.apache.org
>> Subject: Re: Dynamically define WS-Policy for web service client by using Dispatcher and interceptor
>> Hi Andrei or anyone else,
>      
>> When I try to implement external WS-Policy file that can be applied to a WSDL, I came across this link http://cxf.apache.org/docs/how-it-works.html which says
>> wsp:PolicyAttachment can be used to do that BUT it also says "It is not possible however to associate a Policy with an operation or a message this way".
>      
>> Does that mean it's not possible to achieve something like the following with ws:PolicyAttachment right now?
>>          ...
>>          <wsdl:binding name="DoubleItBinding" type="tns:DoubleItPortType">
>>
>>                <wsp:PolicyReference URI="#DoubleItUTSymmetricX509Policy"/>
>>
>>                <soap:binding style="document"
>>               transport="http://schemas.xmlsoap.org/soap/http" />
>>               
>>                <wsdl:operation name="DoubleIt">
>>               <soap:operation soapAction=""/>
>>               
>>               <wsdl:input>
>>                   <soap:body use="literal"/>
>>                  <wsp:PolicyReference URI="#DoubleItBinding_DoubleIt_Input_Policy"/>
>>               </wsdl:input>
>>               
>>               <wsdl:output>
>>                  <soap:body use="literal"/>
>>                  <wsp:PolicyReference URI="#DoubleItBinding_DoubleIt_Output_Policy"/>
>>               </wsdl:output>
>>                </wsdl:operation>
>>                
>>           </wsdl:binding>
>>           
>>           ...
>>           
>>           <wsp:Policy wsu:Id="DoubleItUTSymmetricX509Policy">
>>              ....
>>           </wsp:Policy>
>>
>>           <wsp:Policy wsu:Id="DoubleItBinding_DoubleIt_Input_Policy">
>>              ....
>>           </wsp:Policy>
>>
>>           <wsp:Policy wsu:Id="DoubleItBinding_DoubleIt_Output_Policy">
>>              ....
>>           </wsp:Policy>
>>          .....
>>
> This is definitely supported in CXF. See https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/bindings/BindingPropertiesTest.java in system test as a sample.
>
> In PolicyAttachment AppliesTo CXF currently supports:
> - wsa:EndpointReferenceType (http://www.w3.org/TR/ws-policy-attach/#ExternalPolicyAttachment ) and
> - wsp:URI (http://www.w3.org/TR/ws-policy-attach/#uri-domain-expression) domain expressions.
> wsp:URI provides #wsdl11.service, #wsdl11.port, #wsdl11.portType, #wsdl11.binding, #wsdl11.operation, #wsdl11.name. Still not supported are wsdl11.input, wsdl11.output, wsdl11.fault (see https://svn.apache.org/repos/asf/cxf/trunk/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/external/Wsdl11XPointerDomainExpression.java ).
>      
>>      * Does it make sense to use wsa:Action within ws:PolicyAttachment to associate WS-Policy with wsdl:input, wsdl:output and wsdl:binding to achieve similar thing as above
>>         without WSDL being aware this?
>>      
>>         i.e.
>>         
>>          <!-- this is adapted from /apache-cxf-2.7.6-src/distribution/src/main/release/samples/ws_policy/src/main/resources/addr-external.xml -->
>>          <attachments xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsa="http://www.w3.org/2005/08/addressing">
>>                  <wsp:PolicyAttachment>
>>                  <wsp:AppliesTo>
>>                      <wsa:EndpointReference>
>>                      
>>                      <!-- Can we use IRI/URI that represents wsdl:input, wsdl:output and wsdl:binding of wsa:Action here??? -->
>>                      <wsa:Address>http://localhost:9000/SoapContext/SoapPort</wsa:Address>
>>                      
>>                      </wsa:EndpointReference>
>>                  </wsp:AppliesTo>
>>                  <wsp:Policy>
>>                      <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
>>                      <wsp:Policy/>
>>                      </wsam:Addressing>
>>                  </wsp:Policy>
>>                  
>>                   <wsp:Policy>
>>                      ....
>>                  </wsp:Policy>
>>                  
>>                   ...
>>                  
>>                  </wsp:PolicyAttachment>
>>               </attachments>
>>         
>>      The link http://cxf.apache.org/docs/how-it-works.html seems to suggest implementing DomainExpressionBuilder interface which seems a bit heavy.
> I would recommend either to embed policies in your wsdl or use PolicyAttachment with AppliesTo wsa:EndpointReferenceType or wsp:URI (#wsdl11.service, #wsdl11.port, #wsdl11.portType, #wsdl11.binding, #wsdl11.operation, #wsdl11.name).
>
>>       
>>      Does anyone have best practice advice on how to apply external WS-Policy file to WSDL like above? Or maybe my approach is totally wrong. I can't seem to find existing example
>>      in CXF source that does this.
> That depends on your use case. If policy is unique for the wsdl, it make sense to embed it directly to wsdl.
> If you reuse and share the policies between different wsdls, PolicyAttachment is useful.
>
> As a sample take a look in:
> - https://svn.apache.org/repos/asf/cxf/trunk/rt/ws/policy/src/test/java/org/apache/cxf/ws/policy/attachment/external JUnit tests
> - https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/policy/SslUsernamePasswordAttachmentService.java system test
>
>>        
>>      Thanks,
>>      Sam
> Regards,
> Andrei.
>
> On 31/10/2013 4:10 a.m., Andrei Shakirin wrote:
> Hi,
>
> The preparation of the sample code will take a bit time.
> Meanwhile you use:
> - the blog http://ashakirin.blogspot.de/2012/02/using-ws-policy-in-cxf-projects.html to dynamically set policy and XKMS crypto implementation
> - and XKMS crypto implementation https://svn.apache.org/repos/asf/cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/XkmsCryptoProvider.java as basis for your custom crypto.
>
> Regards,
> Andrei.
>
> -----Original Message-----
> From: Sam [mailto:j2eedodo@gmail.com]
> Sent: Dienstag, 29. Oktober 2013 09:51
> To: users@cxf.apache.org
> Subject: Re: Dynamically define WS-Policy for web service client by using
> Dispatcher and interceptor
>
> Hi Andrei,
>
> Sample code in GitHub will be great. My scenario is to have dynamic policy
> changes and keystore config. Static Dispatch client is simply not that
> impressive.
>
> Thanks,
> Sam
>
> On 29/10/2013 3:21 a.m., Andrei Shakirin wrote:
> Hi,
>
> 1. Applying WS-Policy to Dispatcher client dynamically.
>       The question is it really required in your scenario that Dispatcher client
> should dynamically react on policy changes between the calls.
>       If no, you could try to avoid setting policy via interceptor through
> POLICY_OVERRIDE  message property
> (http://cxf.547215.n5.nabble.com/Dynamicall-y-define-WS-Policy-in-CXF-
> td5713085.html). It will be enough to set policy in the Dispatch client
> statically.
>       If yes, than own interceptor and POLICY_OVERRIDE message property
> will be only the solution.
>
> 2. Config of encryption & signing dynamically at runtime
>       Yes, doing that through Crypto provider is a right way, you can also look
> how it is implemented in XKMS service
> (https://svn.apache.org/repos/asf/cxf/trunk/services/xkms/xkms-
> client/src/main/java/org/apache/cxf/xkms/crypto/impl/XkmsCryptoProvider
> .java ) and considerate to reuse XKMS service
> (http://ashakirin.blogspot.de/2013/04/cxf-security-getting-certificates-
> from.html).
>
> Both solutions dynamic policy mechanism and custom crypto provider are
> working in some projects I was involved.
> If you like, I could distil the code, publish it on the GitHub and reference
> from my blog.
>
> Regards,
> Andrei.
>
>
> -----Original Message-----
> From: Sam [mailto:j2eedodo@gmail.com]
> Sent: Sonntag, 27. Oktober 2013 13:40
> To: users@cxf.apache.org
> Subject: Dynamically define WS-Policy for web service client by using
> Dispatcher and interceptor
>
> 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/j
> ava/ 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-certific
> ates-
> 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-certific
> ates-
> 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
>
>


RE: Dynamically define WS-Policy for web service client by using Dispatcher and interceptor

Posted by Andrei Shakirin <as...@talend.com>.
Hi,

>From: Sam [mailto:j2eedodo@gmail.com] 
>Sent: Sonntag, 3. November 2013 12:38
>To: Andrei Shakirin
>Cc: users@cxf.apache.org
>Subject: Re: Dynamically define WS-Policy for web service client by using Dispatcher and interceptor

>Hi Andrei or anyone else,
    
>When I try to implement external WS-Policy file that can be applied to a WSDL, I came across this link http://cxf.apache.org/docs/how-it-works.html which says 
>wsp:PolicyAttachment can be used to do that BUT it also says "It is not possible however to associate a Policy with an operation or a message this way".
    
>Does that mean it's not possible to achieve something like the following with ws:PolicyAttachment right now?
>        ...
>        <wsdl:binding name="DoubleItBinding" type="tns:DoubleItPortType">
>
>              <wsp:PolicyReference URI="#DoubleItUTSymmetricX509Policy"/>
>
>              <soap:binding style="document"
>             transport="http://schemas.xmlsoap.org/soap/http" />
>             
>              <wsdl:operation name="DoubleIt">
>             <soap:operation soapAction=""/>
>             
>             <wsdl:input>
>                 <soap:body use="literal"/>
>                <wsp:PolicyReference URI="#DoubleItBinding_DoubleIt_Input_Policy"/>
>             </wsdl:input>
>             
>             <wsdl:output>
>                <soap:body use="literal"/>
>                <wsp:PolicyReference URI="#DoubleItBinding_DoubleIt_Output_Policy"/>
>             </wsdl:output>
>              </wsdl:operation>
>              
>         </wsdl:binding>
>         
>         ...
>         
>         <wsp:Policy wsu:Id="DoubleItUTSymmetricX509Policy">
>            ....
>         </wsp:Policy>
>
>         <wsp:Policy wsu:Id="DoubleItBinding_DoubleIt_Input_Policy">
>            ....
>         </wsp:Policy>
>
>         <wsp:Policy wsu:Id="DoubleItBinding_DoubleIt_Output_Policy">
>            ....
>         </wsp:Policy>
>        .....
>

This is definitely supported in CXF. See https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/bindings/BindingPropertiesTest.java in system test as a sample.

In PolicyAttachment AppliesTo CXF currently supports:
- wsa:EndpointReferenceType (http://www.w3.org/TR/ws-policy-attach/#ExternalPolicyAttachment ) and
- wsp:URI (http://www.w3.org/TR/ws-policy-attach/#uri-domain-expression) domain expressions.
wsp:URI provides #wsdl11.service, #wsdl11.port, #wsdl11.portType, #wsdl11.binding, #wsdl11.operation, #wsdl11.name. Still not supported are wsdl11.input, wsdl11.output, wsdl11.fault (see https://svn.apache.org/repos/asf/cxf/trunk/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/external/Wsdl11XPointerDomainExpression.java ).
    
>    * Does it make sense to use wsa:Action within ws:PolicyAttachment to associate WS-Policy with wsdl:input, wsdl:output and wsdl:binding to achieve similar thing as above
>       without WSDL being aware this?
>    
>       i.e. 
>       
>        <!-- this is adapted from /apache-cxf-2.7.6-src/distribution/src/main/release/samples/ws_policy/src/main/resources/addr-external.xml -->
>        <attachments xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsa="http://www.w3.org/2005/08/addressing">
>                <wsp:PolicyAttachment>
>                <wsp:AppliesTo>
>                    <wsa:EndpointReference>
>                    
>                    <!-- Can we use IRI/URI that represents wsdl:input, wsdl:output and wsdl:binding of wsa:Action here??? -->
>                    <wsa:Address>http://localhost:9000/SoapContext/SoapPort</wsa:Address>
>                    
>                    </wsa:EndpointReference>
>                </wsp:AppliesTo>
>                <wsp:Policy>
>                    <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
>                    <wsp:Policy/>
>                    </wsam:Addressing>
>                </wsp:Policy>
>                
>                 <wsp:Policy>
>                    ....
>                </wsp:Policy>
>                
>                 ...
>                
>                </wsp:PolicyAttachment>    
>             </attachments>
>       
>    The link http://cxf.apache.org/docs/how-it-works.html seems to suggest implementing DomainExpressionBuilder interface which seems a bit heavy.

I would recommend either to embed policies in your wsdl or use PolicyAttachment with AppliesTo wsa:EndpointReferenceType or wsp:URI (#wsdl11.service, #wsdl11.port, #wsdl11.portType, #wsdl11.binding, #wsdl11.operation, #wsdl11.name).

>     
>    Does anyone have best practice advice on how to apply external WS-Policy file to WSDL like above? Or maybe my approach is totally wrong. I can't seem to find existing example 
>    in CXF source that does this.

That depends on your use case. If policy is unique for the wsdl, it make sense to embed it directly to wsdl.
If you reuse and share the policies between different wsdls, PolicyAttachment is useful.

As a sample take a look in:
- https://svn.apache.org/repos/asf/cxf/trunk/rt/ws/policy/src/test/java/org/apache/cxf/ws/policy/attachment/external JUnit tests
- https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/policy/SslUsernamePasswordAttachmentService.java system test

>      
>    Thanks,
>    Sam

Regards,
Andrei.

On 31/10/2013 4:10 a.m., Andrei Shakirin wrote:
Hi,

The preparation of the sample code will take a bit time.
Meanwhile you use:
- the blog http://ashakirin.blogspot.de/2012/02/using-ws-policy-in-cxf-projects.html to dynamically set policy and XKMS crypto implementation 
- and XKMS crypto implementation https://svn.apache.org/repos/asf/cxf/trunk/services/xkms/xkms-client/src/main/java/org/apache/cxf/xkms/crypto/impl/XkmsCryptoProvider.java as basis for your custom crypto.

Regards,
Andrei.

-----Original Message-----
From: Sam [mailto:j2eedodo@gmail.com]
Sent: Dienstag, 29. Oktober 2013 09:51
To: users@cxf.apache.org
Subject: Re: Dynamically define WS-Policy for web service client by using
Dispatcher and interceptor

Hi Andrei,

Sample code in GitHub will be great. My scenario is to have dynamic policy
changes and keystore config. Static Dispatch client is simply not that
impressive.

Thanks,
Sam

On 29/10/2013 3:21 a.m., Andrei Shakirin wrote:
Hi,

1. Applying WS-Policy to Dispatcher client dynamically.
     The question is it really required in your scenario that Dispatcher client
should dynamically react on policy changes between the calls.
     If no, you could try to avoid setting policy via interceptor through
POLICY_OVERRIDE  message property
(http://cxf.547215.n5.nabble.com/Dynamicall-y-define-WS-Policy-in-CXF-
td5713085.html). It will be enough to set policy in the Dispatch client
statically.
     If yes, than own interceptor and POLICY_OVERRIDE message property
will be only the solution.

2. Config of encryption & signing dynamically at runtime
     Yes, doing that through Crypto provider is a right way, you can also look
how it is implemented in XKMS service
(https://svn.apache.org/repos/asf/cxf/trunk/services/xkms/xkms-
client/src/main/java/org/apache/cxf/xkms/crypto/impl/XkmsCryptoProvider
.java ) and considerate to reuse XKMS service
(http://ashakirin.blogspot.de/2013/04/cxf-security-getting-certificates-
from.html).

Both solutions dynamic policy mechanism and custom crypto provider are
working in some projects I was involved.
If you like, I could distil the code, publish it on the GitHub and reference
from my blog.

Regards,
Andrei.


-----Original Message-----
From: Sam [mailto:j2eedodo@gmail.com]
Sent: Sonntag, 27. Oktober 2013 13:40
To: users@cxf.apache.org
Subject: Dynamically define WS-Policy for web service client by using
Dispatcher and interceptor

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/j
ava/ 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-certific
ates-
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-certific
ates-
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