I use Apache-CXF WS for SOAP client. Side SOAP endpoint has security (username/password) requirement. Also I use org.eclipse.persistence.eclipselink for changing an JAXBContextFactory, because default factory generates redundant namespaces in request.
With default JAXB client sends username token in header:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-5ec36563-1289-4272-a820-2df93385246a">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
...
</soap:Body>
</soap:Envelope>
But with MOXY JAXBContextFactory client doesn't send security header:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
>> NO HEADER <<
<soap:Body>
...
</soap:Body>
</soap:Envelope>
I tried to find some info in documentation, but no success.
My CXF SOAP client configuration:
<jaxws:client id="side_service_client"
wsdlLocation="side_service.wsdl"
serviceClass="com.example.SideService"
address="${side_service_url}"
xmlns:bfns="http://www.example.com/side_service/"
serviceName="bfns:side_service">
<jaxws:properties>
<entry key="security.username" value="${sideServiceUsername}"/>
<entry key="security.password" value="${sideServicePassword}"/>
<entry key="schema-validation-enabled" value="false"/>
</jaxws:properties>
</jaxws:client>
Apache CXF version - 3.4.10 org.eclipse.persistence.eclipselink version - 2.6.9
Maybe someone has already encountered such a problem and knows the direction of the solution?
Thankls for any answers =)
I was found solution for my question.
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${apache.cxf.version}</version>
</dependency>
ServerPasswordCallback.java
package com.your.domain.configuration;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.wss4j.common.ext.WSPasswordCallback;
/**
* Setup username token to outbound message manually.
*/
public class ServerPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword("YOUR_PASSWORD_VALUE");
}
}
springAppContext.xml
...
<bean id="myPasswordCallback" class="com.your.domain.configuration.ServerPasswordCallback"/>
<jaxws:client id="some_client"
wsdlLocation="some_client.wsdl"
serviceClass="com.your.domain.ServiceClass"
address="${addressUrl}">
...
<jaxws:outInterceptors>
<bean id="securityInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordText"/>
<entry key="user" value="YOUR_USERNAME"/>
<entry key="passwordCallbackRef" value-ref="myPasswordCallback"/>
</map>
</constructor-arg>
</bean>
</jaxws:outInterceptors>
...
</jaxws:client>
...