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?
Creating a JAX-WS handler for SOAP header information To create a JAX-WS handler to access SOAP header information, first create a basic Java API for XML Web Services (JAX-WS) handlers for your export or import. It will create stubs for the methods. You next need to implement the handleMessage method.
You can add soap header information to method calls by decorating the methods in the proxy class generated from the wsdl with the SoapHeader attribute. For example wsdl.exe will generate client proxy class Reference. cs for the web service reference when you "Add Web Reference".
Data can be transferred in SOAP header (JaxWS) by using @WebParam(header = true):
@WebMethod(operationName = "SendRequest", action = "http://abcd.ru/") @Oneway public void sendRequest( @WebParam(name = "Message", targetNamespace = "http://abcd.ru/", partName = "Message") Data message, @WebParam(name = "ServiceHeader", targetNamespace = "http://abcd.ru/", header = true, partName = "ServiceHeader") Header serviceHeader);
If you want to generate a client with SOAP Headers, you need to use -XadditionalHeaders:
wsimport -keep -Xnocompile -XadditionalHeaders -Xdebug http://12.34.56.78:8080/TestHeaders/somewsdl?wsdl -d /home/evgeny/DEVELOPMENT/JAVA/gen
If don't need @Oneway web service, you can use Holder:
@WebMethod(operationName = "SendRequest", action = "http://abcd.ru/") public void sendRequest( @WebParam(name = "Message", targetNamespace = "http://abcd.ru/", partName = "Message") Data message, @WebParam(name = "ServiceHeader", targetNamespace = "http://abcd.ru/", header = true, partName = "ServiceHeader") Holder<Header> serviceHeader);
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 toWSBindingProvider
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With