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

Reply via email to