title: Calling a soap webservice from java with nonce in security headers
body: <p>I am trying to call a webservice from java. This is basically not that difficult, except that the webservice expects some security in the form of a username and password and a nonce.
  When I try to call the webservice from SoapUi, I see that the raw message looks like this:</p>
  
  <pre><code>&lt;soapenv:Envelope xmlns:sch="http://somedomain.com/pe/ws/schema"
      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;
      &lt;soapenv:Header&gt;
          &lt;wsse:Security soapenv:mustUnderstand="1"
              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"&gt;
              &lt;wsse:UsernameToken wsu:Id="UsernameToken-E70691ACBDEFEC750814238295617871"&gt;
                  &lt;wsse:Username&gt;usr&lt;/wsse:Username&gt;
                  &lt;wsse:Password
                      Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
                      &gt;pw&lt;/wsse:Password&gt;
                  &lt;wsse:Nonce
                      EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
                      &gt;4smQZF5KMSktEXrQc0v5yw==&lt;/wsse:Nonce&gt;
                  &lt;wsu:Created&gt;2015-02-13T12:12:41.784Z&lt;/wsu:Created&gt;
              &lt;/wsse:UsernameToken&gt;
          &lt;/wsse:Security&gt;
      &lt;/soapenv:Header&gt;
      &lt;soapenv:Body&gt;
          &lt;sch:EventSubmitRequest&gt;
              &lt;sch:Event&gt;
                  &lt;sch:EventId&gt;392&lt;/sch:EventId&gt;
                  &lt;sch:Recoverable&gt;false&lt;/sch:Recoverable&gt;
              &lt;/sch:Event&gt;
          &lt;/sch:EventSubmitRequest&gt;
      &lt;/soapenv:Body&gt;
  &lt;/soapenv:Envelope&gt;
  </code></pre>
  
  <p>The obvious elements in the message are the Username, Password and Created, but what puzzles me is the nonce. In the example this field has the value 4smQZF5KMSktEXrQc0v5yw==, but this value difference upon each request (which makes sense, since according to wikipedia, a nonce is an arbitrary number used only once). When searching around, I can't find any usable examples of how to generate the nonce in java (Although I did find some php examples here on stack overflow, but I can't easily verify weather they work) . While I don't mind construction this nonce myself, I'm wondering if this is really necessary, I kind of would expect this to be standard functionality in java.</p>
  
  <p>Below is the code I'm using:</p>
  
  <pre><code>import java.text.SimpleDateFormat;
  import java.util.Calendar;
  import javax.xml.namespace.QName;
  import javax.xml.soap.*;
  import javax.xml.transform.*;
  import javax.xml.transform.stream.*;
  
  public class soaptest {
  
      public static void main(String args[]) {
          try {
              // Create SOAP Connection
              SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
              SOAPConnection soapConnection = soapConnectionFactory.createConnection();
  
              // Send SOAP Message to SOAP Server
              String url = "http://142.10.10.52:8080/pe/ws/pe/";
              SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
  
              // Process the SOAP Response
              printSOAPResponse(soapResponse);
  
              soapConnection.close();
          } catch (Exception e) {
              System.err.println("Error occurred while sending SOAP Request to Server");
              e.printStackTrace();
          }
      }
  
      private static SOAPMessage createSOAPRequest() throws Exception {
          MessageFactory messageFactory = MessageFactory.newInstance();
          SOAPMessage soapMessage = messageFactory.createMessage();
          SOAPPart soapPart = soapMessage.getSOAPPart();
  
          SOAPEnvelope envelope = soapPart.getEnvelope();
          SOAPHeader header = soapMessage.getSOAPHeader();
  
          SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
  
          SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
          usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
  
          SOAPElement username = usernameToken.addChildElement("Username", "wsse");
          username.addTextNode("usr");
  
          SOAPElement password = usernameToken.addChildElement("Password", "wsse");
          password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
          password.addTextNode("pw");
  
          SOAPElement nonce = usernameToken.addChildElement("Nonce", "wsse");
          nonce.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
          nonce.addTextNode("???");
  
          SOAPElement created = usernameToken.addChildElement("Created", "wsse");
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
          Calendar c1 = Calendar.getInstance();
          created.addTextNode(sdf.format(c1.getTime()));
  
          String serverURI = "http://somedomain.com/pe/ws/schema";
  
          envelope.addNamespaceDeclaration("sch", serverURI);
  
          // SOAP Body
          SOAPBody soapBody = envelope.getBody();
          SOAPElement soapBodyElem = soapBody.addChildElement("EventSubmitRequest", "sch");
          SOAPElement soapBodyElem1 = soapBody.addChildElement("Event", "sch");
          soapBodyElem.addChildElement(soapBodyElem1);
  
          SOAPElement soapBodyElem2 = soapBodyElem1.addChildElement("EventId", "sch");
          soapBodyElem2.addTextNode("392");
          SOAPElement soapBodyElem3 = soapBodyElem1.addChildElement("Recoverable", "sch");
          soapBodyElem3.addTextNode("false");
  
          MimeHeaders headers = soapMessage.getMimeHeaders();
          headers.addHeader("SOAPAction", serverURI  + "EventSubmitRequest");
  
          soapMessage.saveChanges();
  
          /* Print the request message */
          System.out.print("Request SOAP Message = ");
          soapMessage.writeTo(System.out);
          System.out.println();
  
          return soapMessage;
      }
  
      /**
       * Method used to print the SOAP Response
       */
      private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
          TransformerFactory transformerFactory = TransformerFactory.newInstance();
          Transformer transformer = transformerFactory.newTransformer();
          Source sourceContent = soapResponse.getSOAPPart().getContent();
          System.out.print("\nResponse SOAP Message = ");
          StreamResult result = new StreamResult(System.out);
          transformer.transform(sourceContent, result);
      }
  
  }
  </code></pre>