Many thanks to David, Dan and Jarek for the help, I have tested my code after removing the out interceptor from the server side and it just worked.
Request: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsse:Security xmlns:wsse=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"><wsse:UsernameToken xmlns:wsse=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-14195893"><wsse:Username xmlns:wsse=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">system</wsse:Username><wsse:Password xmlns:wsse=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" Type=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">manager</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><add xmlns="http://jws.samples.geronimo.apache.org "><value1>2</value1><value2>2</value2></add></soap:Body></soap:Envelope> Response: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/ "><soap:Body> <addResponse xmlns="http://jws.samples.geronimo.apache.org "><return>4</return></addResponse></soap:Body></soap:Envelope> Best Regards, Rahul On Mon, Jul 27, 2009 at 5:37 PM, rahul.soa <[email protected]> wrote: > Many Thanks Dan for pointing to the root cause. > > So does that mean server will not send the secure SOAP header in the > response? I thought initially that client will also receive the secured > response from server. May be I was wrong. > > I will try it by removing the WSS4JOutInterceptor from the server side to > see if it works. > > Thanks again for your help. > > Best Regards, > Rahul > On Mon, Jul 27, 2009 at 5:23 PM, Daniel Kulp <[email protected]> wrote: > >> On Mon July 27 2009 3:42:04 am rahul.soa wrote: >> > Many Thanks David for your efforts in helping me out. That will be very >> > helpful. >> >> Well, I did the grep for you. It's coming from WSS4J, not CXF, in: >> src/org/apache/ws/security/message/token/UsernameToken.java >> >> Most likely, you DON'T want to setup the WSS4JOutInterceptor on the server >> side to have a UserNameToken. That's not normally a usual occurrence. >> (why >> would the server be sending BACK a Username?) >> >> Dan >> >> >> >> > Will it be a good idea to forward my doubt to CXF and WSS4J developers >> > community? >> >> > >> > Best Regards, >> > Rahul >> > >> > On Mon, Jul 27, 2009 at 1:35 AM, David Jencks <[email protected] >> >wrote: >> > > I chatted with Rahul on IRC a bit, and it looks to me as if his code >> is >> > > doing what cxf and wss4j expect. >> > > I think the next step is to figure out exactly where the fault is >> coming >> > > from. >> > > >> > > I would grep the cxf and wss4j source code for "but a password is >> > > needed". If that doesn't find the source I would run geronimo in the >> > > debugger and put a breakpoint at the end of the handle(CallbackHandler >> > > handler) method and step through the code. >> > > >> > > I also wonder if the fault is from the WSS4jOutInterceptor. >> > > >> > > thanks >> > > david jencks >> > > >> > > On Jul 26, 2009, at 4:20 PM, rahul.soa wrote: >> > > >> > > Just one amendment here in my speculation about the fault cause. >> > > >> > > I wrote this in the previous thread, >> > > >> > > >> > > "but I dont know why I am getting this error pwd == null but a >> password >> > > is needed at pwcb.setPassword(passwd);" >> > > >> > > Now, i dont think this fault is coming from here >> > > pwcb.setPassword(passwd); >> > > >> > > as I have tested it by removing the following code to be sure about >> the >> > > fault >> > > >> > > if (!pwcb.getPassword().equals(passwd)) { >> > > LOG.debug("wrong password"); >> > > throw new IOException("wrong password"); >> > > } else { >> > > LOG.debug("I am setting the password here ::::" >> + >> > > passwd); >> > > pwcb.setPassword(passwd); >> > > } >> > > >> > > from ServerPasswordHandler and I still have the same fault error in >> the >> > > response. >> > > >> > > Please correct me if I am wrong somewhere. I am not sure where this >> fault >> > > come from? >> > > >> > > Thank you. >> > > >> > > Best Regards, >> > > Rahul >> > > >> > > On Mon, Jul 27, 2009 at 12:07 AM, rahul.soa >> <[email protected]>wrote: >> > >> Hello David/Devs, >> > >> >> > >> Objective: trying to set web service security at serverside: >> > >> >> > >> I am getting an error while accessing the secured webservice. The >> soap >> > >> fault I am receiving is below: >> > >> >> > >> *Response:* >> > >> >> > >> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/ >> > >> >> "><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring> >> > >>*pwd == null but a password is needed* >> > >> </faultstring></soap:Fault></soap:Body></soap:Envelope> >> > >> * >> > >> Request:* >> > >> >> > >> <soap:Envelope >> > >> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/ >> "><soap:Header><wss >> > >>e:Security xmlns:wsse=" >> > >> >> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secex >> > >>t-1.0.xsd" soap:mustUnderstand="1"><wsse:UsernameToken xmlns:wsse=" >> > >> >> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secex >> > >>t-1.0.xsd" xmlns:wsu=" >> > >> >> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utili >> > >>ty-1.0.xsd" wsu:Id="UsernameToken-32620541"><wsse:Username >> xmlns:wsse=" >> > >> >> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secex >> > >>t-1.0.xsd">system</wsse:Username><wsse:Password xmlns:wsse=" >> > >> >> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secex >> > >>t-1.0.xsd" Type=" >> > >> >> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-p >> > >> >>rofile-1.0#PasswordText">manager</wsse:Password></wsse:UsernameToken></ws >> > >>se:Security></soap:Header><soap:Body><add >> > >> xmlns="http://jws.samples.geronimo.apache.org >> > >> >> "><value1>2</value1><value2>2</value2></add></soap:Body></soap:Envelope> >> > >> >> > >> >> > >> How I am trying to do is, >> > >> >> > >> 1. At, server side (in the doPublish method of CXFEndpoint), I am >> > >> setting the WSS4JIn/OutInterceptor property for user token (please >> note: >> > >> this is not generic code at this moment) >> > >> >> > >> protected void doPublish(String baseAddress) { >> > >> // XXX: assume port 8080 by default since we don't know the >> > >> actual port >> > >> // at startup >> > >> String address = (baseAddress == null) ? " >> http://localhost:8080" >> > >> >> > >> : baseAddress; >> > >> >> > >> JaxWsServerFactoryBean svrFactory = new >> > >> GeronimoJaxWsServerFactoryBean(); >> > >> svrFactory.setBus(bus); >> > >> svrFactory.setAddress(address + this.portInfo.getLocation()); >> > >> svrFactory.setServiceFactory(serviceFactory); >> > >> svrFactory.setStart(false); >> > >> svrFactory.setServiceBean(implementor); >> > >> >> > >> if >> (HTTPBinding.HTTP_BINDING.equals(implInfo.getBindingType())) >> > >> { svrFactory.setTransportId(" >> > >> http://cxf.apache.org/bindings/xformat"); >> > >> } >> > >> >> > >> // to receive the incoming username/password in soap request >> > >> Map inProps = new HashMap(); >> > >> inProps.put(WSHandlerConstants.ACTION, >> > >> WSHandlerConstants.USERNAME_TOKEN); >> > >> inProps.put(WSHandlerConstants.PASSWORD_TYPE, >> > >> WSConstants.PW_TEXT); >> > >> inProps.put(WSHandlerConstants.USER, "system"); >> > >> inProps.put(WSHandlerConstants.PW_CALLBACK_REF, >> > >> new *ServerPasswordHandler*()); >> > >> >> > >> server = svrFactory.create(); >> > >> // to receive the secure header >> > >> WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); >> > >> // to send the secure soap header >> > >> WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(inProps); >> > >> init(); >> > >> >> > >> org.apache.cxf.endpoint.Endpoint endpoint = getEndpoint(); >> > >> >> > >> endpoint.getInInterceptors().add(wssIn); >> > >> endpoint.getInInterceptors().add( >> > >> new >> > >> org.apache.cxf.binding.soap.saaj.SAAJInInterceptor()); >> > >> >> > >> endpoint.getOutInterceptors().add(wssOut); >> > >> endpoint.getOutInterceptors().add( >> > >> new >> > >> org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor()); >> > >> LOG.debug("So far set the interceptor"); >> > >> // >> > >> >> > >> if (getBinding() instanceof SOAPBinding >> > >> && this.portInfo.isMTOMEnabled() != null) { >> > >> ((SOAPBinding) getBinding()).setMTOMEnabled(this.portInfo >> > >> .isMTOMEnabled()); >> > >> } >> > >> >> > >> server.start(); >> > >> LOG.debug("Invoked"); >> > >> >> > >> } >> > >> >> > >> I am setting up the login authentication and setting the password in >> the >> > >> Server Handler, like following: >> > >> >> > >> >> > >> public class ServerPasswordHandler implements CallbackHandler { >> > >> >> > >> private static final Logger LOG = LoggerFactory >> > >> ..getLogger(ServerPasswordHandler.class); >> > >> >> > >> public void handle(Callback[] callbacks) throws IOException, >> > >> UnsupportedCallbackException { >> > >> >> > >> for (int i = 0; i < callbacks.length; i++) { >> > >> WSPasswordCallback pwcb = (WSPasswordCallback) >> callbacks[i]; >> > >> if (pwcb.getUsage() == >> > >> WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) { >> > >> LOG.debug("I am inside the ServerPasswordHandler"); >> > >> String username = pwcb.getIdentifier(); >> > >> String passwd = pwcb.getPassword(); >> > >> >> > >> LoginContext context = null; >> > >> try { >> > >> // Login authentication goes here >> > >> // use the existing security realm for the moment >> > >> for testing >> > >> context = ContextManager.login("geronimo-admin", >> > >> new >> > >> UsernamePasswordCallbackHandler(username, passwd)); >> > >> // ContextManager.login(realm, callbackHandler, >> > >> // configuration) >> > >> context.login(); >> > >> LOG.debug("login is successful"); >> > >> } catch (LoginException e) { >> > >> LOG.debug("login failed"); >> > >> throw new IOException("Unable to verify " + >> username >> > >> + " and " + passwd); >> > >> } >> > >> >> > >> //TODO: what to do with subject >> > >> Subject subject = context.getSubject(); >> > >> ContextManager.setCallers(subject, subject); >> > >> >> > >> if (!pwcb.getPassword().equals(passwd)) { >> > >> LOG.debug("wrong password"); >> > >> throw new IOException("wrong password"); >> > >> } else { >> > >> *LOG.debug("I am setting the password here >> > >> >> > >> ::::" >> > >> >> > >> + passwd);* >> > >> * pwcb.setPassword(passwd);* >> > >> } >> > >> >> > >> } >> > >> >> > >> } >> > >> } >> > >> >> > >> } >> > >> >> > >> >> > >> In the traces, I can see the password value is "manager" which is >> sent >> > >> by client >> > >> I am setting the password here ::::manager >> > >> >> > >> but I dont know why I am getting this error pwd == null but a >> password >> > >> is needed at pwcb.setPassword(passwd); >> > >> >> > >> Login authentication goes sucessful when the client provides the >> correct >> > >> username and password (which are "system and "manager" respectively). >> > >> and goes unsuccessful otherwise. >> > >> >> > >> The full trace from the geronimo.log is attached here: (there are >> some >> > >> debug statement to see the traces ) >> > >> >> > >> >> > >> >> > >> 2009-07-27 01:26:17,809 DEBUG [JAXWSServiceReference] Initializing >> > >> service with: >> > >> >> file:/home/rahul/new_workspace1/GerominoWebClient/WEB-INF/wsdl/Calculato >> > >>rService.wsdl {http://jws.samples.geronimo.apache.org}Calculator >> > >> 2009-07-27 01:26:18,031 DEBUG [PortMethodInterceptor] Set address >> > >> property: http://localhost:8080/GerominoWeb/calculator >> > >> 2009-07-27 01:26:18,031 DEBUG [CXFPortMethodInterceptor] Username and >> > >> password sent by Clients are : system manager >> > >> 2009-07-27 01:26:18,126 DEBUG [CXFPasswordHandler] I HAVE SET THE >> > >> VALUES system and manager >> > >> 2009-07-27 01:26:18,142 DEBUG [ServerPasswordHandler] I am inside the >> > >> ServerPasswordHandler >> > >> 2009-07-27 01:26:18,143 DEBUG [UsernamePasswordCallbackHandler] WHAT >> I >> > >> GOT HERE: system and manager >> > >> 2009-07-27 01:26:18,143 DEBUG [UsernamePasswordCallbackHandler] >> Username >> > >> set to: system >> > >> 2009-07-27 01:26:18,143 DEBUG [UsernamePasswordCallbackHandler] >> password >> > >> set to: manager >> > >> 2009-07-27 01:26:18,144 DEBUG [UsernamePasswordCallbackHandler] WHAT >> I >> > >> GOT HERE: system and manager >> > >> 2009-07-27 01:26:18,144 DEBUG [UsernamePasswordCallbackHandler] >> Username >> > >> set to: system >> > >> 2009-07-27 01:26:18,144 DEBUG [UsernamePasswordCallbackHandler] >> password >> > >> set to: manager >> > >> *2009-07-27 01:26:18,144 DEBUG [ServerPasswordHandler] login is >> > >> successful* >> > >> *2009-07-27 01:26:18,145 DEBUG [ServerPasswordHandler] I am setting >> the >> > >> password here ::::manager* >> > >> *2009-07-27 01:26:18,313 INFO [PhaseInterceptorChain] Interceptor >> has >> > >> thrown exception, unwinding now pwd == null but a password is needed* >> > >> 2009-07-27 01:26:18,376 ERROR [log] /jaxws-calculator/calculator >> > >> *javax.xml.ws.soap.SOAPFaultException: pwd == null but a password is >> > >> needed* >> > >> at >> > >> >> org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145) >> > >> at $Proxy67.add(Unknown Source) >> > >> at CalculatorServlet.doGet(CalculatorServlet.java:42) >> > >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:693) >> > >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:806) >> > >> at >> > >> >> org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:521) >> > >> at >> > >> >> org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:43 >> > >>5) at >> > >> >> org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java >> > >>:118) at >> > >> >> org.eclipse.jetty.server.session.SessionHandler.handle(SessionHandler.ja >> > >>va:179) at >> > >> >> org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler. >> > >>java:928) at >> > >> >> org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:370 >> > >>) at >> > >> >> org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.j >> > >>ava:862) at >> > >> >> org.apache.geronimo.jetty7.handler.GeronimoWebAppContext.doScope(Geronim >> > >>oWebAppContext.java:107) at >> > >> >> org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java >> > >>:116) at >> > >> >> org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(Context >> > >>HandlerCollection.java:243) at >> > >> >> org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollect >> > >>ion.java:126) at >> > >> >> org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.ja >> > >>va:115) at org.eclipse.jetty.server.Server.handle(Server.java:337) >> > >> at >> > >> >> org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.jav >> > >>a:561) at >> > >> >> org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(Ht >> > >>tpConnection.java:943) at >> > >> org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:530) at >> > >> org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:203) >> > >> at >> > >> >> org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:414) >> > >> at >> > >> >> org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint >> > >>.java:437) at >> > >> org.apache.geronimo.pool.ThreadPool$1.run(ThreadPool.java:214) at >> > >> >> org.apache.geronimo.pool.ThreadPool$ContextClassLoaderRunnable.run(Threa >> > >>dPool.java:344) at >> > >> >> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecuto >> > >>r.java:886) at >> > >> >> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.ja >> > >>va:908) at java.lang.Thread.run(Thread.java:619) >> > >> *Caused by: org.apache.cxf.binding.soap.SoapFault: pwd == null but a >> > >> password is needed* >> > >> at >> > >> >> org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarsh >> > >>alFault(Soap11FaultInInterceptor.java:75) at >> > >> >> org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleM >> > >>essage(Soap11FaultInInterceptor.java:46) at >> > >> >> org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleM >> > >>essage(Soap11FaultInInterceptor.java:35) at >> > >> >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorC >> > >>hain.java:226) at >> > >> >> org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage >> > >>(AbstractFaultChainInitiatorObserver.java:96) at >> > >> >> org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMess >> > >>age(CheckFaultInterceptor.java:69) at >> > >> >> org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMess >> > >>age(CheckFaultInterceptor.java:34) at >> > >> >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorC >> > >>hain.java:226) at >> > >> org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:641) at >> > >> >> org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResp >> > >>onseInternal(HTTPConduit.java:2102) at >> > >> >> org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResp >> > >>onse(HTTPConduit.java:1980) at >> > >> >> org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTP >> > >>Conduit.java:1905) at >> > >> >> org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:66) >> > >> at >> > >> org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:600) >> > >> at >> > >> >> org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingI >> > >>nterceptor.handleMessage(MessageSenderInterceptor.java:62) at >> > >> >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorC >> > >>hain.java:226) at >> > >> org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:469) at >> > >> org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:299) at >> > >> org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:251) at >> > >> org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) >> at >> > >> >> org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124) >> > >> ... 28 more >> > >> >> > >> >> > >> Can you please let me know or correct me, why this is happening?, I >> > >> think if password is set correctly in the pwcb.setPassword(passwd); >> > >> then client should be able to access the secure web service. I am >> > >> getting the correct password "manager" (as seen in the logs) and >> setting >> > >> the same but I dont know why I am getting this fault. >> > >> >> > >> Second thing is, I am not sure what to do with subject? >> > >> >> > >> Am I missing something in the above code? Please correct me and help >> me >> > >> in this. >> > >> >> > >> Many Thanks in advance for your response. >> > >> >> > >> Regards, >> > >> Rahul >> >> -- >> Daniel Kulp >> [email protected] >> http://www.dankulp.com/blog >> > >
