Thank you guys. I was playing with it this morning and get them to work.
Basically my client classpath is messed up and I cleaned them up and
re-added one by one then it works. I understand java-first may not be the
best approach but thank you all for the help and it finally works. Really
appreciate every single one of you.
Let me summarize what I did in case in the future other people may have the
same problem.
What I have and what I want to do:
- Java-first for the services.
- wsdl2java to generate client code.
- Adding simple username/password security on top of that.
How I code:
- Add an annotation before the WS Java interface (assuming there is an
implementation class):
@InInterceptors(interceptors={"com.abc.company.ServerInterceptor"}) to
specify this server is going to use this ServerInterceptor class. The
reason I am doing this is because I want to specify all my configuration in
the code(ServerInterceptor constructor) instead of in cxf.xml or
spring-config.xml
- ServerInterceptor.java, basically extands WSS4JInInterceptor, and
configure it in the constructor.
public class ServerInterceptor extends WSS4JInInterceptor{
public ServerInterceptor() {
super();
HashMap hm = new HashMap();
hm.put("action", "UsernameToken");
hm.put("passwordType", "PasswordText");
hm.put("passwordCallbackClass",
"edu.uci.rice.kim.service.wssecurity.ServerPasswordCallback");
this.setProperties(hm);
}
public void handleMessage(SoapMessage msg) {
System.out.println("in handleMessage");
super.handleMessage(msg);
}
}
- ServerPasswordCallback
public class ServerPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
// TODO Auto-generated method stub
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if ("joe".equals(pc.getIdentifier())) {
pc.setPassword("joespassword");
}
}
}
- Now the client side (pretty much follow Glen Mazza's example at
http://www.jroller.com/gmazza/entry/cxf_usernametoken_profile). This will
tell the client to use WSS4JOutInterceptor with callback class
ClientPasswordCallback.
// you should get something similar to the following 2 lines after
wsdl2java generates the client code
UciRoleServiceSOAP_Service uciRoleServiceSOAP_Service = new
UciRoleServiceSOAP_Service();
UciRoleServiceSOAP uciRoleServiceSOAP =
uciRoleServiceSOAP_Service.getUciRoleServiceSOAPPort();
Map ctx = ((BindingProvider)uciRoleServiceSOAP).getRequestContext();
ctx.put("ws-security.username", "joe");
ctx.put("ws-security.callback-handler",
ClientPasswordCallback.class.getName());
// instead of above line can also do:
// ctx.put("ws-security.password", "joespassword");
// Alternative CXF interceptor config method
org.apache.cxf.endpoint.Client client =
org.apache.cxf.frontend.ClientProxy.getClient(uciRoleServiceSOAP);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
Map outProps = new HashMap();
outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
outProps.put(WSHandlerConstants.USER, "joe");
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientPasswordCallback.class.getName());
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
uciRoleServiceSOAP.wsmethod()....
- ClientPasswordCallback
public class ClientPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws
IOException,UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if ("joe".equals(pc.getIdentifier())) {
pc.setPassword("joespassword");
} // else {...} - can add more users, access DB, etc.
}
}
- That's all you have to do.
Regards,
~Adam
--
View this message in context:
http://cxf.547215.n5.nabble.com/Interceptors-for-WS-security-tp5722285p5724479.html
Sent from the cxf-user mailing list archive at Nabble.com.