15

i have a NO-.net webservice from oracle To access i need to add the soap header. How can i add the soap header in java?

Authenticator.setDefault(new ProxyAuthenticator("username", "password"));
                System.getProperties().put("proxySet", "true");
                System.setProperty("http.proxyHost", "IP");
                System.setProperty("http.proxyPort", "port");




                proxy = new RegPresMed_Service(new URL("webservice")).getRegPresMed();
                ((BindingProvider) proxy).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "realwebservice");
                ((BindingProvider) proxy).getRequestContext().put("com.sun.xml.ws.request.timeout", new Integer(60000));
                ((BindingProvider) proxy).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "webserviceUsername");
                ((BindingProvider) proxy).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "webservicePassword");

is this necessary?

 ((BindingProvider) proxy).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "webserviceUsername");
                    ((BindingProvider) proxy).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "webservicePassword");

my soap header is like this:

<wsse:Security soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken wsu:Id="UsernameToken-6"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>username</wsse:Username>
        <wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
        <wsse:Nonce
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">randomnaumber==</wsse:Nonce>
        <wsu:Created>dateCreated</wsu:Created>
    </wsse:UsernameToken>
</wsse:Security>
skaffman
  • 398,947
  • 96
  • 818
  • 769
Luis
  • 2,665
  • 8
  • 44
  • 70

3 Answers3

4

I struggled to get this working. That's why I'll add a complete solution here:

My objective is to add this header to the SOAP envelope:

   <soapenv:Header>
      <urn:OTAuthentication>
         <urn:AuthenticationToken>TOKEN</urn:AuthenticationToken>
      </urn:OTAuthentication>
   </soapenv:Header>
  1. First create a SOAPHeaderHandler class.

    import java.util.Set;
    import java.util.TreeSet;
    
    import javax.xml.namespace.QName;
    import javax.xml.soap.SOAPElement;
    import javax.xml.soap.SOAPEnvelope;
    import javax.xml.soap.SOAPFactory;
    import javax.xml.soap.SOAPHeader;
    import javax.xml.ws.handler.MessageContext;
    import javax.xml.ws.handler.soap.SOAPHandler;
    import javax.xml.ws.handler.soap.SOAPMessageContext;
    
    public class SOAPHeaderHandler implements SOAPHandler<SOAPMessageContext> {
    
        private final String authenticatedToken;
    
        public SOAPHeaderHandler(String authenticatedToken) {
            this.authenticatedToken = authenticatedToken;
        }
    
        public boolean handleMessage(SOAPMessageContext context) {
            Boolean outboundProperty =
                    (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
            if (outboundProperty.booleanValue()) {
                try {
                    SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
                    SOAPFactory factory = SOAPFactory.newInstance();
                    String prefix = "urn";
                    String uri = "urn:api.ecm.opentext.com";
                    SOAPElement securityElem =
                            factory.createElement("OTAuthentication", prefix, uri);
                    SOAPElement tokenElem =
                            factory.createElement("AuthenticationToken", prefix, uri);
                    tokenElem.addTextNode(authenticatedToken);
                    securityElem.addChildElement(tokenElem);
                    SOAPHeader header = envelope.addHeader();
                    header.addChildElement(securityElem);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                // inbound
            }
            return true;
        }
    
        public Set<QName> getHeaders() {
            return new TreeSet();
        }
    
        public boolean handleFault(SOAPMessageContext context) {
            return false;
        }
    
        public void close(MessageContext context) {
            //
        }
    }
    
    1. Add the handler to the proxy. Note that according javax.xml.ws.Binding's documentation: "If the returned chain is modified a call to setHandlerChain is required to configure the binding instance with the new chain."

    Authentication_Service authentication_Service = new Authentication_Service();
    
    Authentication basicHttpBindingAuthentication = authentication_Service.getBasicHttpBindingAuthentication();
    String authenticatedToken = "TOKEN";
    
    List<Handler> handlerChain = ((BindingProvider)basicHttpBindingAuthentication).getBinding().getHandlerChain();
    handlerChain.add(new SOAPHeaderHandler(authenticatedToken));
    ((BindingProvider)basicHttpBindingAuthentication).getBinding().setHandlerChain(handlerChain);
    
riskop
  • 1,693
  • 1
  • 16
  • 34
Eduardo Briguenti Vieira
  • 4,351
  • 3
  • 37
  • 49
  • I have very similar objective to add the auth token to the SOAP header for OT connection. I have followed the same code but i am getting "SOAPFaultException: OTDS username and password are required." exception even though i have passed valid authenticated token. Could you please guide me where am i going wrong ? (i am able to connect with OT in a stand alone java app but not when i run as a webservice) – Tony Mar 14 '17 at 14:51
  • 1
    Try to see what you are sending as the SOAP envelop. You can do it by adding a handler. Follow the answer in this post http://stackoverflow.com/questions/1945618/tracing-xml-request-responses-with-jax-ws – Eduardo Briguenti Vieira Mar 14 '17 at 15:03
  • By adding the handler, the complete SOAP envelope will be printed in the log, and you will see what is wrong. – Eduardo Briguenti Vieira Mar 14 '17 at 15:04
  • Thanks a lot for your input. I could figured out what is going wrong in the header with the link you have pointed out. Somehow the element was not getting added to the SOAP header. Thanks – Tony Mar 17 '17 at 05:44
  • Actually I had the same problem. That's why I sent this tip ! :-) – Eduardo Briguenti Vieira Mar 20 '17 at 17:30
  • Wow man, exactly the same what I needed (I see you were also struggling with DocWeb CWS :-) :) – clementino Dec 29 '17 at 09:29
  • I had great help from this example! In my case, I had to replace `SOAPHeader header = envelope.addHeader()` with `SOAPHeader header = envelope.getHeader()` as my message already had a header and it is not possible to add several headers. – Daniel Wahlberg Mar 18 '18 at 23:21
2

i was facing the same issue and solved it by removing the xmlns:wsu attribute.Try not adding it in the usernameToken.Hope this solves your issue too.

Alpesh003
  • 329
  • 8
  • 24
0

Maven dependency

    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.ws.security</groupId>
        <artifactId>wss4j</artifactId>
        <version>1.6.19</version>
    </dependency>    

Configuration class

import org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor;

@Configuration
public class ConfigurationClass{

@Bean
public Wss4jSecurityInterceptor securityInterceptor() {
    Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
    wss4jSecurityInterceptor.setSecurementActions("UsernameToken");
    wss4jSecurityInterceptor.setSecurementMustUnderstand(true);
    wss4jSecurityInterceptor.setSecurementPasswordType("PasswordText");
    wss4jSecurityInterceptor.setSecurementUsername("123456789011");
    wss4jSecurityInterceptor.setSecurementPassword("TestPass123");
    return wss4jSecurityInterceptor;
}

Result xml

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
    <wsse:Security
        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" 
        SOAP-ENV:mustUnderstand="1">
        <wsse:UsernameToken wsu:Id="UsernameToken-F57F40DC89CD6998E214700450735811">
            <wsse:Username>123456789011</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPass123</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
    ...
    something
    ...
</SOAP-ENV:Body>

Alexey
  • 11
  • 3