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

Reply via email to