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