How to sign SOAP request in Jmeter

In this post we will see how to test a SOAP web service in JMeter. Using JMeter, we can do both functional testing as well as load testing of a SOAP web services. As we know that web services are headless so, we can’t use the record and playback feature of JMeter to record the web service requests. Hence, we need to create the Sampler requests manually. In this tutorial, we will use the “SOAP/XML-RPC Request” sampler to create and send the SOAP request.

SOAP/XML-RPC Request

The SOAP/XML-RPC Request sampler is used to send a SOAP or an XML-RPC request to a webservice. This sampler creates an HTTP POST request(as SOAP is based POST method) with the request body specified in the “SOAP/XML-RPC Data” field. We can specify the SOAPAction in the SOAPAction field after checking the Send SOAPActioncheckbox.

Steps to test a SOAP Web service using JMeter-

  1. Add a Thread Group, name it and configure it with the required values for Number of Threads, Rampup and Loop count.
  2. Within the Thread Group, add a “SOAP/XML-RPC Request” sampler.
    Right Click on Thread Group -> Hover over Add -> Sampler -> SOAP/XML-RPC Request.
  3. Configure the “SOAP/XML-RPC Request” sampler-

Specify the SOAP Web Service WSDL URL.
If SOAPAction is required then – Check the SOAPAction checkbox and specify its value. Otherwise, you can keep the checkbox unchecked and field blank.



Place the SOAP request in the “SOAP/XML-RPC Data” field.

4. Add the desired Listeners like – View Result Tree.

5. Schedule and run the test with desired number of Users in the Thread Group.

We can improve the test by adding “CSV Data Set Config” to parameterize the test by fetching the test data from an external file. Furthermore, we can add “Assertions” to validate the web service response (especially used in functional testing).

Now major issue is how to sign and /or encrypt the soap request. I used the jmeter-wssecurity addin downloaded from: https://github.com/tilln/jmeter-wssecurity 

All steps are documented at the add in page itself but challenge is how to add the timestamp. Here are three ways by which we can accomplish this task.

Solution 1: To resolve that I embedded the groovy script in the SOAP request. It will insert the created timestamp and expire timestamp. Please find the template in the attachment.

 <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">
      <wsu:Timestamp>
         <wsu:Created>
        ${__groovy(def now=new Date(); 
    vars.putObject('now'\,now);now.format("yyyy-MM-dd'T'HH:mm:ss.SSXXX"\,TimeZone.getTimeZone('UTC')))}
    </wsu:Created>
    <wsu:Expires>${__groovy(use(groovy.time.TimeCategory){
    (vars.getObject('now') + 5.minutes).format("yyyy-MM-dd'T'HH:mm:ss.SSXXX"\,
            TimeZone.getTimeZone('UTC'))})
          }
          </wsu:Expires>
      </wsu:Timestamp>
 </wsse:Security>

Solution 2:  Another way to achieve this is use BeanShell script. For that use variables in xml input and add a beanshell preprocessor.

 <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">
      <wsu:Timestamp>
         <wsu:Created>${#CREATED#}</wsu:Created>
         <wsu:Expires>${#EXPIRES#}</wsu:Expires>
      </wsu:Timestamp>
 </wsse:Security>

Here is bean shell code:

import org.apache.jmeter.protocol.http.sampler.SoapSampler; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.TimeZone; 
try { long ctmilli = System.currentTimeMillis();
dformat1.setTimeZone(TimeZone.getTimeZone("UTC")); dtime.setTime(ctmilli);
vars.put("#EXPIRES#",timeExpire.toString()); } 
catch (Throwable ex) { log.error("Error in Beanshell", ex); throw ex; }

Solution 3:
  Another way to achieve this is use JSR223 script. For that use variables in xml input and add a JSR223 preprocessor.

 <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">
      <wsu:Timestamp>
         <wsu:Created>${#CREATED#}</wsu:Created>
         <wsu:Expires>${#EXPIRES#}</wsu:Expires>
      </wsu:Timestamp>
 </wsse:Security>

Here is JSR code:

import java.text.SimpleDateFormat;
import org.apache.jmeter.protocol.http.sampler.SoapSampler;
 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date now = new Date();
Date expires = new Date(now.getTime() + (10 * 60 * 1000));
System.out.println("Date"+ now);
String timeCreated = sdf.format(now);
String timeExpire = sdf.format(expires);
 
vars.put("#CREATED#",timeCreated.toString());
vars.put("#EXPIRES#",timeExpire.toString());
 
/*
String data = sampler.getXmlData();
data = data.replaceFirst("#CREATED#", wsuCreated);
data = data.replaceFirst("#EXPIRES#", wsuExpires);
sampler.setXmlData(data);
 
*/
 
log.info ("JSR223 log");
//log.info (data);

Happy testing !!

One thought on “How to sign SOAP request in Jmeter

  1. Ved says:

    Really helpful, good information

Leave a Reply

Your email address will not be published. Required fields are marked *