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.
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.