2

I've been trying to write a webservice client using Apache Axis in Intellij Idea 13 and having some difficulties. I already can connect that webservice with a .net c# project and now i need to achieve that with java. WebService wants username and password within a security header.

Here is the response from WebService:

nested fault: No Username Security Token found in the WS block with actor: current actor

Here is the code that i use.

SomeWebServiceServiceLocator locator = new SomeWebServiceServiceLocator();
SomeWebServicePortBindingStub stub = (SomeWebServicePortBindingStub) locator.getSomeWebServicePort();
stub.setUsername("usr111");
stub.setPassword("pass111");

SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
javax.xml.soap.SOAPPart sOAPPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = sOAPPart.getEnvelope();
SOAPHeader header = envelope.getHeader();

if (header == null) {
            System.out.println("no header yet, create one");
            header = envelope.addHeader();
        }
        SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

        Name tUserTokenElementName = envelope.createName("UsernameToken", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        SOAPElement tUserTokenElement = security.addChildElement(tUserTokenElementName);
        tUserTokenElement.removeNamespaceDeclaration("wsse");
        tUserTokenElement.addNamespaceDeclaration("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
        //
        tUserTokenElement.addAttribute(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", "u"), "UsernameToken-usr111");

        // user name child
        Name tUsernameElementName = envelope.createName("Username", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        SOAPElement tUsernameElement = tUserTokenElement.addChildElement(tUsernameElementName);
        tUsernameElement.removeNamespaceDeclaration("wsse");
        tUsernameElement.addTextNode("usr111");

        // password child
        Name tPasswordElementName = envelope.createName("Password", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        SOAPElement tPasswordElement = tUserTokenElement.addChildElement(tPasswordElementName);
        tPasswordElement.removeNamespaceDeclaration("wsse");
        tPasswordElement.addTextNode("pass111");
        tPasswordElement.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");

        Element assertion = (Element) security;
        SOAPHeaderElement header0 = new SOAPHeaderElement(assertion);
        stub.setHeader(header0);

That code generates following header.

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:actor="" soapenv:mustUnderstand="0" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:UsernameToken wsu:Id="UsernameToken-usr111" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:Username>usr111</wsse:Username>
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass111</wsse:Password>
</wsse:UsernameToken> </wsse:Security>

I also trace the working .net cs application's connection with Fiddler but failed to trace my java call. Here is the working request's header.

<s:Header>
    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo1zQ7/YYhJpArMKDUdofV4QAAAAAvGLoItf+KkC8k4KQjqtXUK0D00UQcXJBtCFGkgP0qBkACQAA</VsDebuggerCausalityData>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <o:UsernameToken u:Id="uuid-de9cefc3-6ab9-407f-8658-7ecf007559bc-17">
            <o:Username>usr111</o:Username>
            <o:Password o:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass111</o:Password>
        </o:UsernameToken>
    </o:Security>
</s:Header>

Also here's a example xml provided from webservice owner

<soapenv:Header>
  <wsse:Security soapenv:mustUnderstand="0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
     <wsse:UsernameToken wsu:Id="UsernameToken-11111111" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
       <wsse:Username>someuser</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">*****</wsse:Password>
     </wsse:UsernameToken>
  </wsse:Security>

There is also two .crt certificates provided by owner of webservice. I added them to the javakeystore but it helps nothing. Finally i can't request that webservice with SoapUI.

Çağdaş Tunca
  • 873
  • 1
  • 11
  • 24

1 Answers1

8

Okay, if somebody else faces with this kind of error, this method below worked for me. I can't remember where i found this but thanks to the owner. . thanks to him.

void addWsSecurityHeader(org.apache.axis.client.Stub binding, String wsUser,String wsPass)throws SOAPException {

    // Create the top-level WS-Security SOAP header XML name.
    QName headerName = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");
    SOAPHeaderElement header = new SOAPHeaderElement(headerName);
    //  no intermediate actors are involved.
    header.setActor(null);
    // not important, "wsse" is standard
    header.setPrefix("wsse");
    header.setMustUnderstand(true);

    // Add the UsernameToken element to the WS-Security header
    SOAPElement utElem = header.addChildElement("UsernameToken");
    SOAPElement userNameElem = utElem.addChildElement("Username");
    userNameElem.removeContents();
    userNameElem.setValue(wsUser);

    SOAPElement passwordElem = utElem.addChildElement("Password");
    passwordElem.setValue(wsPass);
    // Finally, attach the header to the binding.
    binding.setHeader(header);
}

Also for tracing what i send and recieve i used this

Community
  • 1
  • 1
Çağdaş Tunca
  • 873
  • 1
  • 11
  • 24