views:

1943

answers:

2

Hello,

I am trying to create a standalone client to consume some web services. I must add my username and password to the SOAP Header. I tried adding the credentials as follows:

OTSWebSvcsService service = new OTSWebSvcsService();
OTSWebSvcs port = service.getOTSWebSvcs();

BindingProvider prov = (BindingProvider)port;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myusername");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");

...

When I call a method on the service I get the following exception:

com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5048E: One of "SOAP Header" elements required.

What am I doing wrong? How would I add these properties to the SOAP Header?

Edited: I was using JAX-WS 2.1 included in JDK6. I am now using JAX-WS 2.2. I now get the following exception:

com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5509E: A security token whose type is [http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken] is required.

How do I go about creating this token?

+4  A: 

Not 100% sure as the question is missing some details but if you are using JAX-WS RI, then have a look at Adding SOAP headers when sending requests:

The portable way of doing this is that you create a SOAPHandler and mess with SAAJ, but the RI provides a better way of doing this.

When you create a proxy or dispatch object, they implement BindingProvider interface. When you use the JAX-WS RI, you can downcast to WSBindingProvider which defines a few more methods provided only by the JAX-WS RI.

This interface lets you set an arbitrary number of Header object, each representing a SOAP header. You can implement it on your own if you want, but most likely you'd use one of the factory methods defined on Headers class to create one.

import com.sun.xml.ws.developer.WSBindingProvider;

HelloPort port = helloService.getHelloPort();  // or something like that...
WSBindingProvider bp = (WSBindingProvider)port;

bp.setOutboundHeader(
  // simple string value as a header, like <simpleHeader>stringValue</simpleHeader>
  Headers.create(new QName("simpleHeader"),"stringValue"),
  // create a header from JAXB object
  Headers.create(jaxbContext,myJaxbObject)
);

Update your code accordingly and try again. And if you're not using JAX-WS RI, please update your question and provide more context information.

Update: It appears that the web service you want to call is secured with WS-Security/UsernameTokens. This is a bit different from your initial question. Anyway, to configure your client to send usernames and passwords, I suggest to check the great post Implementing the WS-Security UsernameToken Profile for Metro-based web services (jump to step 4). Using NetBeans for this step might ease things a lot.

Pascal Thivent
A: 

Client java ( ADD LLIBRARY D:\IBM\SDP\runtimes\base_v61_stub\runtimes\com.ibm.jaxws.thinclient_6.1.0.jar )

package com.service.test;

import java.util.Map;

import com.ibm.websphere.wssecurity.wssapi.WSSException; import com.ibm.websphere.wssecurity.wssapi.WSSFactory; import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;

import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken; import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken; import javax.xml.ws.BindingProvider;

import com.service.OperacionesServiceDelegate; import com.service.OperacionesServiceService;

/** * @author DiegoCastaneda * */ public class Test {

public static void main(String[] args) {

    OperacionesServiceService  serv= new OperacionesServiceService();
    OperacionesServiceDelegate del=serv.getOperacionesServicePort();



    // use BindingProvider to hook into message context
    BindingProvider bp = (BindingProvider) del;
    Map<String,Object> requestContext = bp.getRequestContext();



    WSSFactory wssfactory=null;
    try 
    {

        wssfactory = WSSFactory.getInstance();

        WSSGenerationContext generationContext = wssfactory.newWSSGenerationContext();
        //manda el username y el password.

        com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler untCallback=new com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler("adminTraslados","12345",true,true);

        SecurityToken unt=null;

            unt = wssfactory.newSecurityToken(UsernameToken.class,
                    untCallback);

        generationContext.add(unt);

        //procesa el encabezado.
        generationContext.process(requestContext);


    } catch (WSSException e) {
        // TODO Bloque catch generado automáticamente
        e.printStackTrace();
    }


        System.out.println("Resultado "+del.sumar(3,4));


}

}

/////////////////////////////////////////////////////////////////////////////////////////////

WEB client (( ADD LLIBRARY D:\IBM\SDP\runtimes\base_v61_stub\runtimes\com.ibm.jaxws.thinclient_6.1.0.jar )

public String consultarServicio() { System.out.println("LLamando servicio");

    OperacionesServicePortProxy proxy;
    try {



        proxy = new OperacionesServicePortProxy(
                new URL(endpointURL + "?wsdl"), 
                new QName("http://service.com/", "operacionesServiceService"));


        OperacionesServiceDelegate del=proxy._getDescriptor().getProxy();


        // use BindingProvider to hook into message context
        BindingProvider bp = (BindingProvider) del;
        Map<String,Object> requestContext = bp.getRequestContext();



        WSSFactory wssfactory=null;


            wssfactory = WSSFactory.getInstance();

            WSSGenerationContext generationContext = wssfactory.newWSSGenerationContext();
            //manda el username y el password.

            com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler untCallback=new com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler("adminTraslados","12345",true,true);

            SecurityToken unt=null;

                unt = wssfactory.newSecurityToken(UsernameToken.class,
                        untCallback);

            generationContext.add(unt);

            //procesa el encabezado.
            generationContext.process(requestContext);



            System.out.println("Resultado 3+4 = "+del.sumar(3,4));



        } catch (WSSException e) {

            e.printStackTrace();
        }
        catch (MalformedURLException e) {

            e.printStackTrace();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            System.out.println("Fin Llamar Servicio ");
        }



    return null;
}
Diego Castaneda
And what is that?
Pascal Thivent