I'm trying to create a "java first" webservice that will use plain and simple UsernameToken WS-Security. I've attempted to follow the examples from CXF. When I query my wsdl I see no mention of anything ws-security related. I'm using CXF 2.7.5 and I'm trying to do everything with annotations.
The following is my failed attempt:
SampleService.java:
import java.util.ArrayList;
import java.util.Date;
import javax.jws.WebParam;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.apache.cxf.annotations.EndpointProperties;
import org.apache.cxf.annotations.EndpointProperty;
@WebService(targetNamespace="https://test.company.com/ws/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
@EndpointProperties({
@EndpointProperty(key = "action", value="UsernameToken"),
@EndpointProperty(key = "passwordType", value="PasswordText"),
@EndpointProperty(key = "ws-security.callback-handler", value="PasswordHandler"),
//@EndpointProperty(key = "ws-security.validate.token", value="false"),
})
public interface SampleService {
@WebMethod
public String getSample(
@WebParam(name="startDate") Date startDate,
@WebParam(name="endDate") Date endDate);
}
SampleServiceImpl.java:
import java.util.Date;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService(endpointInterface = "SampleService", targetNamespace="https://test.company.com/ws/")
public class SampleServiceImpl implements SampleService {
@Override
@WebMethod
public String getSample(Date startDate, Date endDate) {
StringBuilder sb = new StringBuilder();
sb.append("Start Date: ");
sb.append(startDate.toString());
sb.append("\n");
sb.append("End Date: ");
sb.append(endDate.toString());
return sb.toString();
}
}
PasswordHandler.java:
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.ws.security.WSPasswordCallback;
public class PasswordHandler implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
System.out.println("User: " + pc.getIdentifier());
System.out.println("Password: " + pc.getIdentifier());
System.out.println("Type: " + pc.getType());
if (pc.getIdentifier().equals("joe")) {
// set the password on the callback. This will be compared to the
// password which was sent from the client.
pc.setPassword("password");
}
}
}
SampleServicePublisher.java:
import java.util.HashMap;
import java.util.Map;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
public class SampleServicePublisher {
public static void main(String[] args) {
String URL = "http://localhost:9999/ws/SampleService";
EndpointImpl jaxWsEndpoint =
(EndpointImpl) javax.xml.ws.Endpoint.publish(URL, new SampleServiceImpl());
Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
Map<String,Object> inProps= new HashMap<String,Object>();
// how to configure the properties is outlined below;
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
cxfEndpoint.getInInterceptors().add(wssIn);
Map<String,Object> outProps = new HashMap<String,Object>();
// how to configure the properties is outlined below;
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
// Password type : plain text
inProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
// for hashed password use:
//properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
// Callback used to retrieve password for given user.
inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordHandler.class.getName());
}
}
mvn dependencies:
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.5</version>
</dependency>
<!-- Jetty is needed if you're using the CXFServlet -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-rm</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-addr</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>