Reputation: 1474
I am trying to consume a SOAP web service that requires security using CXF in Mule. I have got it working, but I need to put the password in a config file. I can't find how to pass the password from the config to the flow/callback class. My flow looks like this:
<cxf:jaxws-client
clientClass="za.co.iam.service.identitymanager.intf._1.IdentityManager_Service"
port="IdentityManager"
wsdlLocation="classpath:/wsdl/IdentityManager.wsdl"
operation="CheckUserId" doc:name="CXF">
<cxf:ws-security>
<cxf:ws-config>
<cxf:property key="action" value="UsernameToken Timestamp"/>
<cxf:property key="user" value="${security.username}"/>
<cxf:property key="passwordType" value="PasswordText"/>
<cxf:property key="passwordCallbackClass" value="za.co.iam.IamPasswordCallback"/>
</cxf:ws-config>
</cxf:ws-security>
</cxf:jaxws-client>
<outbound-endpoint address="${iam.webservice}" doc:name="Generic"/>
The IamPasswordCallback
class:
public class IamPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword("********");
}
}
This works fine, but I need to put the password into the config file as well. The way I would normally do it is to make a bean out of IamPasswordCallback
and set the value in the flow and use the bean for the callback handler on the CXF setup, but I don't know what that config should look like. The alternative is to load the property file in the IamPasswordCallback
class, but I believe that is not recommended.
Upvotes: 0
Views: 595
Reputation: 440
If you are using the new wsconsumer component, you can give the user and password directly from config file.
<ws:consumer-config name="Web_Service_Consumer" wsdlLocation="test.wsdl" service="testService" port="test" serviceAddress="${url.endpoint}" doc:name="Web Service Consumer" connectorConfig="HTTP_Request_Config">
<ws:security>
<ws:wss-username-token username="${user}" password="${password}" passwordType="TEXT"/>
</ws:security>
</ws:consumer-config>
If you have to stick with CXF, then you can use a spring bean definition as below:
In your global elements,
<spring:bean id="WSSCallback" name="WSSCallback" class="test.ClientCallback">
<spring:property name="SoapPassword" value="${password}"/>
</spring:bean>
And have the below or similar code in your callback class:
public class ClientCallback implements CallbackHandler {
private String SoapPassword;
public String getSoapPassword() {
return SoapPassword;
}
public void setSoapPassword(String soapPassword) {
SoapPassword = soapPassword;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// set the password for our message.
pc.setPassword(SoapPassword);
}
}
Now in your cxf-client have the below config:
<cxf:jaxws-client enableMuleSoapHeaders="false" doc:name="SOAP" clientClass="client.class" operation="testop" port="testport" wsdlLocation="test.wsdl">
<cxf:ws-security>
<cxf:ws-config>
<cxf:property key="action" value="UsernameToken"></cxf:property>
<cxf:property key="user" value="${user.name}"></cxf:property>
<cxf:property key="passwordType" value="PasswordText"></cxf:property>
<cxf:property key="passwordCallbackRef" value-ref="WSSCallback"></cxf:property>
</cxf:ws-config>
</cxf:ws-security>
</cxf:jaxws-client>
Upvotes: 1