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 <rahul....@googlemail.com>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><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-32620541"><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> > > > 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/CalculatorService.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:435) > at > org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:118) > at > org.eclipse.jetty.server.session.SessionHandler.handle(SessionHandler.java: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.java:862) > at > org.apache.geronimo.jetty7.handler.GeronimoWebAppContext.doScope(GeronimoWebAppContext.java:107) > at > org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:116) > at > org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:243) > at > org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126) > at > org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:115) > at org.eclipse.jetty.server.Server.handle(Server.java:337) > at > org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:561) > at > org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.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(ThreadPool.java:344) > at > java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: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.unmarshalFault(Soap11FaultInInterceptor.java:75) > at > org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:46) > at > org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35) > at > org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226) > at > org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:96) > at > org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69) > at > org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34) > at > org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226) > at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:641) > at > org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:2102) > at > org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1980) > at > org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.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$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) > at > org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.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 >