Glen,

The reason I didn't pull it into the 2.0.x branch is that it technically is a binary incompatible change. The WSS4JOutIntercptor moves from the POST_PROTOCOL phase to the PRE_PROTOCOL phase with it's internal interceptor going into the POST_PROTOCOL. Thus, if a user has an interceptor that has a "addAfter(WSS4JOutInterceptor.class.getName())" type thing, that code would no longer work correctly.

Now, that type of thing is probably quite rare and I would be willing to release-note it for 2.0.8 if it's important enough. I'd just like to see some consensus on that.

The changes in WSS4JInInterceptor are minor and would have no impact. I'm OK merging that, but the Out stuff is a bit more of an issue.

Dan



On Jul 17, 2008, at 9:04 AM, Glen Mazza wrote:


Dan, if you wouldn't mind adding the SAAJ handler to the one WSS4J In/Out Interceptor (one of those two) in the 2.0.x branch where it is missing (the
other one in 2.0.x has it), we can remove this distracting moving part
entirely from the CXF WS-Security documentation. I'll happily do the doc
update once a new 2.0.x is released.

Glen


dkulp wrote:

On Jul 17, 2008, at 12:40 AM, Glen Mazza wrote:


If you're using CXF 2.1+, be sure *not* to add the SAAJ handlers as
you're
doing below.  That's only a 2.0.x thing.


Actually, it's not a big deal if you do add them.   It's smart enough
to check if its needed or not.

Dan


Also, you *might* be able to use more Spring configuration and pull
out more
of that coding, in particular the WSS4JInInterceptor--storing the
username
might be troublesome though:
http://cwiki.apache.org/CXF20DOC/ws-security.html#WS-Security-SpringXMLConfiguration

BTW, I just finished my blog entry on this.  Our code is similar,
but maybe
you can find something else to leverage:
http://www.jroller.com/gmazza/date/20080716

Glen


Gary Weaver wrote:

Just verified that it works to set PW_CALLBACK_REF instead of
PW_CALLBACK_CLASS.

Do you think it would help to have examples on
http://cwiki.apache.org/CXF20DOC/ws-security.html that use
WSHandlerConstants.PW_CALLBACK_REF in addition (or maybe instead?) of
those that use WSHandlerConstants.PW_CALLBACK_CLASS?

This seems like it might be a good idea, since it would probably
increase CXF performance at little to reduce instantiation of a
CallbackHandler via reflection on every call.

HTH,
Gary


Gary Weaver wrote:
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




--
View this message in context:
http://www.nabble.com/configuring-password-for-services-via-Spring-in-Apache-CXF-2.1.1-%28so-that-username%2C-password%2C-endpoint%2C-etc.-can-be-set-on-client-bean-via-Spring%29-tp18491639p18501459.html
Sent from the cxf-user mailing list archive at Nabble.com.


---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog







--
View this message in context: 
http://www.nabble.com/configuring-password-for-services-via-Spring-in-Apache-CXF-2.1.1-%28so-that-username%2C-password%2C-endpoint%2C-etc.-can-be-set-on-client-bean-via-Spring%29-tp18491639p18507332.html
Sent from the cxf-user mailing list archive at Nabble.com.


---
Daniel Kulp
[EMAIL PROTECTED]
http://www.dankulp.com/blog




Reply via email to