JWT Token

Signing a JWT in JMeter for load testing

How to create a JWT in JMeter using JSR223 Sampler?

Mah Noor
Published in
4 min readJan 6, 2022

--

JMeter is a tool used for load and stress testing of APIs. It is completely open-source and provides a vast range of features to work with. This article focuses on how to generate a mock JWT token for authentication and sign it with RS256 algorithm in the jMeter.

What does a JWT comprise of?

A well-formed JWT consists of three concatenated Base64url-encoded strings, separated by dots (.):

  • Header: contains metadata about the type of token and the cryptographic algorithms used to secure its contents.
  • Payload: The payload contains the user information and verifiable security statements, such as the identity/email of the user and the permissions they are allowed.
  • Signature: used to validate if the token is trustworthy and has not been tampered with.

The resulting JWT looks like Header.Payload.Signature

Creation of JWT In JMeter:

Java Libraries Needed:

In the directory where JMeter is installed, Add the following dependencies/JAR files to the class path( i.e. the lib folder):

dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>

Following are the steps to create a JWT in JMeter for authentication:

  1. Create a Test Plan in the jMeter:
A New Test Plan In JMeter

2. Add a setUp thread group. The plan is to create a thread group that runs before the actual Concurrency thread group. A SetUp Thread Group is the best option here as its purpose is to set up the pre-conditions for the load testing.

Add a setUp Thread Group in the test plan

Next, add a User-Defined Variable config element. It will keep the global variable of JWT to use in the required authenticated APIs.

Add a User Defined Config element in the test plan

3. Add a JSR223 Sampler in the setUp thread group.

Add a JSR223 Sampler in setUp thread group

To create a JSON Web Token in JMeter, we will use the JSR223 Sampler in a simple thread group.

One of the key features of JMeter is that it allows the user to write a pre-processing or a post-processing script for the APIs. To implement the JSON web token creation, we can use two of the following scripting samplers:

  1. Bean Shell Scripting
  2. JSR223 Scripting

For the current requirement, we will go with the JSR223 Sampler, to have a faster and high-performing script. Additionally using a pre-processor instead of a sampler is preferred because we need to create the JSON web token one time and then use it in the header for all the authenticated APIs.

Groovy Script for the JSR223 Sampler:

//Import the Required Libraries:import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import io.jsonwebtoken.*;
import java.util.Date;


java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
//Save the Secret key/ Private Key in a variableString SECRET_KEY = "-----BEGIN RSA PRIVATE KEY-----\n" +
****Add your Private Key HERE*
"-----END RSA PRIVATE KEY-----";


PemReader pemReader = new PemReader(new StringReader (SECRET_KEY));
PemObject pemObject = pemReader.readPemObject();
KeyFactory kf = KeyFactory.getInstance("RSA");
byte[] content = pemObject.getContent ();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(content);
PrivateKey pk = kf.generatePrivate (keySpec);
//The RS256 signature algorithm will be used to sign the token in this example SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;//Set the Issued date and expiry date to now
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
//Build the JWT with the JwtBuilderJwtBuilder builder = Jwts.builder()
.signWith (signatureAlgorithm,pk)
.setIssuedAt(now)
.setExpiration(exp)
.setId(id);
//Save the JWT in the compact string in the jmeter variables vars.put("JWT",builder.compact().toString());
log.info(builder.compact().toString());

Using org.bouncycastle.util.io.pem: We will leverage the PemReader and PemObject of the ‘BouncyCastle’ java library because it reads the private key irrespective of the format of the key.

4. Add a listener to the thread group.

Add a listner to the thread group

5. Run the thread group and check the console logs.

The JWT is created and saved in the jmeter variable

Conclusion:

The JWT is created and it can be used in the header manager for the API calls for authentication.

Happy Stress Testing! :)

--

--