The first thing I should have done is to look at the WSS4J source... ;)
The code in WSS4J 1.5.4 to get your CallbackHandler is (
http://svn.apache.org/viewvc/webservices/wss4j/tags/1_5_4/src/org/apache/ws/security/handler/WSHandler.java?view=markup
):
--- start code ---
/**
* Get the password callback class and get an instance
* <p/>
*/
protected CallbackHandler getPasswordCB(RequestData reqData)
throws WSSecurityException {
Object mc = reqData.getMsgContext();
CallbackHandler cbHandler = null;
String callback =
getString(WSHandlerConstants.PW_CALLBACK_CLASS, mc);
if (callback != null) {
Class cbClass = null;
try {
cbClass = Loader.loadClass(getClassLoader(reqData
.getMsgContext()), callback);
} catch (ClassNotFoundException e) {
throw new WSSecurityException(
"WSHandler: cannot load password callback class: "
+ callback, e);
}
try {
cbHandler = (CallbackHandler) cbClass.newInstance();
} catch (java.lang.Exception e) {
throw new WSSecurityException(
"WSHandler: cannot create instance of password
callback: "
+ callback, e);
}
} else {
cbHandler = (CallbackHandler) getProperty(mc,
WSHandlerConstants.PW_CALLBACK_REF);
if (cbHandler == null) {
throw new WSSecurityException(
"WSHandler: no reference in callback property");
}
}
return cbHandler;
}
--- end code ---
So it looks like setting the instance of your CallbackHandler is as easy
as setting:
MyCallbackHandler myCallbackHander = new MyCallbackHandler();
myCallbackHander.setPassword(password);
outProps.put(WSHandlerConstants.PW_CALLBACK_REF, myCallbackHander);
:) !
Here are the revised files:
--- start example code MyClient.java ---
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
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;
import java.util.HashMap;
import java.util.Map;
public class MyClient {
private String endpoint;
private String user;
private String password;
private Log log = LogFactory.getLog(MyClient.class);
protected void testService() {
MyService service = new MyService(null);
MyServicePortType portType = service.getMyServicePort();
Client client = ClientProxy.getClient(portType);
// set username and password
// see: http://cwiki.apache.org/CXF20DOC/ws-security.html
Endpoint clientEndpoint = client.getEndpoint();
// No security on client-side
Map<String, Object> inProps = new HashMap<String, Object>();
inProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.NO_SECURITY);
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
clientEndpoint.getInInterceptors().add(wssIn);
clientEndpoint.getInInterceptors().add(new SAAJInInterceptor());
// 2.0.x only; not needed in 2.1+
// Server-side authN
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
outProps.put(WSHandlerConstants.USER, getUser());
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
//outProps.put(WSHandlerConstants.PASSWORD_TYPE,
WSConstants.PW_DIGEST);
MyCallbackHandler myCallbackHander = new MyCallbackHandler();
myCallbackHander.setPassword(password);
outProps.put(WSHandlerConstants.PW_CALLBACK_REF, myCallbackHander);
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
clientEndpoint.getOutInterceptors().add(wssOut);
clientEndpoint.getOutInterceptors().add(new
SAAJOutInterceptor()); // 2.0.x only; not needed in 2.1+
MyServiceResponse response =
portType.someServiceMethod(MyServiceRequest);
return response;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
--- end example code MyClient.java ---
--- start example code MyCallbackHandler.java ---
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
public class MyCallbackHandler implements CallbackHandler {
private static final Log log =
LogFactory.getLog(MyCallbackHandler.class);
private String password;
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword(password);
}
public void setPassword(String password) {
this.password = password;
}
}
--- end example code MyCallbackHandler.java ---
--
Gary Weaver
Internet Framework Services
Office of Information Technology
Duke University