Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. If you are using CXF 2.0.x, you must add the SAAJ(In/Out)Interceptors if you're using WS-Security . (This is done automatically for you with from CXF 2.1 onwards). These enable creation of a DOM tree for each request/response. The support libraries for WS-Security require DOM trees.
  2. The web service provider may not need both in and out WS-Security interceptors. For instance, if you are just requiring signatures on incoming messages, the web service provider will just need an incoming WSS4J interceptor and only the SOAP client will need an outgoing one.

...

Code Block
java
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 ServerPasswordCallback implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

        if (pc.getIdentifer().equals("joe")) {
            // set the password on the callback. This will be compared to the
            // password which was sent from the client.
            pc.setPassword("password");
        }
    }

}

Note that for up to and including CXF 2.3.x, the password validation of the special case of a plain-text password (or any other yet unknown password type) , the password validation is delegated to the callback class, see org.apache.ws.security.processor.UsernameTokenProcessor#handleUsernameToken() method javadoc of the WSS4Jproject. In that case, the ServerPasswordCallback should be something like the following one:

Code Block
java
java
public class ServerPasswordCallback implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

        if (pc.getIdentifer().equals("joe") {
           if (!pc.getPassword().equals("password")) {
                throw new IOException("wrong password");
           }
        }
    }

}

For CXF 2.4 onwards, the callback handler supplies the password for all cases, and the validation is done internally (but can be configured). See <a href="http://coheigea.blogspot.com/2011/02/usernametoken-processing-changes-in.html">here</a> for more information.
On the Client side you'll want to configure the WSS4J outgoing properties:

...

In the case of multiple users with different passwords, use the WSPasswordCallback's getIdentifer() getIdentifier(sic) method to obtain the username of the current SOAP request.

...