As I wrote before it is quite easy to set up a web service proxy with Mule3. in this example I take it a step further and I describe how you can add WS-Security implementation to it. Although in the end this also is quite easy you have to make the correct configuration choices to get everything to work.
The first thing I had to do in my Mule config was to drop the pattern prefix. This took me a while to discover because I think this isn’t very clear in the documentation. Anyway, after that change it is fairly straight forward.
Here is the Mule config I ended up with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?xml version="1.0" encoding="UTF-8"?> <mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:http="http://www.mulesoft.org/schema/mule/http" xsi:schemaLocation=" http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/3.2/mule-cxf.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/3.2/mule-http.xsd"> <flow name="create-client"> <http:inbound-endpoint address="http://localhost:8080/create-client"> <cxf:proxy-service/> </http:inbound-endpoint> <http:outbound-endpoint address="http://localhost:8081/create-client"> <cxf:proxy-client> <cxf:outInterceptors> <spring:bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <spring:constructor-arg> <spring:map> <spring:entry key="action" value="Timestamp Signature" /> <spring:entry key="user" value="${signature.user}" /> <spring:entry key="signaturePropFile" value="ws-security.properties" /> <spring:entry key="passwordCallbackClass" value="nl.redstream.adapter.MyKeystorePasswordCallback"/> </spring:map> </spring:constructor-arg> </spring:bean> <spring:bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" /> </cxf:outInterceptors> </cxf:proxy-client> </http:outbound-endpoint> </flow> <flow name="get-client-status"> <http:inbound-endpoint address="http://localhost:8081/get-status"> <cxf:proxy-service> <cxf:inInterceptors> <spring:bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <spring:bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <spring:constructor-arg> <spring:map> <spring:entry key="action" value="Signature" /> <spring:entry key="signaturePropFile" value="ws-security.properties" /> </spring:map> </spring:constructor-arg> </spring:bean> </cxf:inInterceptors> </cxf:proxy-service> </http:inbound-endpoint> <http:outbound-endpoint address="http://localhost:8080/get-status"> <cxf:proxy-client /> </http:outbound-endpoint> </flow> </mule> |
As you can see I have added two flows. The first flow is ‘create-client’. I receive the incoming call from my own ‘inside’-application and add a signature and timestamp to it before I forward it to the ‘outside’ service.
The second flow works the other way around: I receive a signed message from the ‘outside’ client app and I need to validate this before I pas the message to my ‘inside’ application. To create the signature I need the password for to make use of my private key in the keystore. To supply this password I simply implemented the PasswordCallbackHandler that returns the corresponding password by looking it up in a property file. For more info about configuring the WS-security with CFX see here and also I found this entry about Apache WSS4J quite handy.
The security property file that is referred to in my Mule config file contains the following:
1 2 3 4 | org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=JKS org.apache.ws.security.crypto.merlin.file=/KeyStores/redstreamKeystore.jks org.apache.ws.security.crypto.merlin.keystore.password=myPassword |
For both flows I added the logging interceptor which is quite handy during testing and developing to see what is received and sent out. In the next post I will show how to generate the keystores and configure SoapUI to test the proxy manually.
Leave a Reply