cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Weaver <gary.wea...@duke.edu>
Subject Re: configuring password for services via Spring in Apache CXF 2.1.1 (so that username, password, endpoint, etc. can be set on client bean via Spring)
Date Wed, 16 Jul 2008 20:41:53 GMT
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


Mime
View raw message