Create a JSON Web Token (JWT) using the DataWeave JWT Library
- January 31, 2024
Recently, there was a requirement to create a JSON Web Token (JWT) within the Mulesoft application and send it as an OAuth token to the backend for authentication. After conducting some research, I discovered several methods for creating JWT, such as using Java code, DataWeave code or JWT sign module. Implementing Java code can be complex. DataWeave code may not work for the RSA algorithm. The client preferred not to use a custom module like JWT Sign module. Finally, I found the DataWeave JWT Library available in the Mulesoft Exchange.
In this article, I will describe the process of creating JWT using the DataWeave JWT Library available in Mulesoft Exchange, which supports both HMAC and RSA algorithms.
JSON Web Token
JSON Web Token (JWT) is an open standard that provides a mechanism for securely transmitting data between parties in the form of a JSON object. JWTs are relatively small in size, making it possible to send them through a URL, POST parameter or HTTP header, facilitating quick transmission.
JSON Web Token structure
JSON Web Tokens are made up of three parts separated by dots (.), which are:
- Header: The first part is the Base64-URL encoded header, which typically consists of two fields: the type of the token (JWT) and the signing algorithm being used (HMAC or RSA).
For example:
{
"alg": "RS256",
"typ": "JWT"
}
- Payload: The second part of the token is the payload, which consists of Base64-URL encoded claims. Claims include details about the user and some additional data.
For example:
{
"sub": "jwt-demo@test.com",
"aud": "https://test.mulesoft.com",
"exp": "1661508617"
}
- Signature: To create the signature part, we need to take the Base64-URL encoded header, the Base64-URL encoded payload, a private key or secret key based on the algorithm type (HMAC or RSA), the algorithm specified in the header, and then sign it.
In the case of HMAC signature, a secret key is used by the client to sign the JWT, and the same secret key is employed by the server to validate the JWT.
In the case of RSA signature, the client uses the private key to sign the JWT, and the server uses the corresponding public key to validate it. This ensures that the message remains unchanged in transit, and the sender of the JWT is verified.
Below is an example of a JWT for the above-encoded header and payload, signed with a private key.
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqd3QtZ
GVtb0B0ZXN0LmNvbSIsImF1ZCI6Imh0dHBzOi8vdGVz
dC5tdWxlc29mdC5jb20iLCJleHAiOjE2NjE1MDg2MT
d9.WnXOmrIv2SRF940x5qGuiRUkPJ1
4rBMnDRc53NLCf8LbJXEiwiSlKaulQGwRwBsBB
G1C2DcANVqabC1KkeCen5D1dKaaabGo8BtV83
qiP9FyKIhRgl81ldzOZ0QuybqBF78-Tq8LpjAX6W4HIlU5Im6MhgAR
nWKillxPbnwK8t_AVxIFxl2JW_h0gNbqT9tnOR2Y
DFm3gNlfLvHEu01FgI8LW9VQLvEuCsEMSCaz7-t1JsQ9nH8wGoVnmU0NgCyRBMd3F0
hoCDzIP1PMJSceOHVdlK4hsmsjmDLsVUT0aInhoW
qeyVcJkoULmBB34VUazV0yjXLzup26jUvfFxkwlA
Walkthrough
Step 1: Navigate to the DataWeave JWT Library in the MuleSoft Exchange (https://www.mulesoft.com/exchange/68ef9520-24e9-4cf2-b2f5-620025690913/data-weave-jwt-library/)
Step 2: Copy the dependency snippet from the exchange and paste it into the dependencies section of your project’s pom.xml file.
This will import the DataWeave JWT Library from MuleSoft Exchange into your MuleSoft application.
Step 3: Add a transform message in your flow to create JWT.
Create JWT with RSA Algorithm.
Add the transform message to read the private key in the Mule application and store it in a variable.
output application/json
—
readUrl("classpath://pkcs1-rsa256-privatekey.pem","text/plain") replace "\r" with ""
Here, the private key is present under the src/main/resources folder, and we are reading the private key into the Mule flow using the DataWeave readUrl function. You can also load the private key using the file read connector or any other method, such as loading from Azure Key Vault, AWS Secret Manager, etc., depending on the use case requirements. Additionally, you need to check the new line character in your private key. If it is “\r\n” instead of “\n,” then you need to remove the extra “\r” as mentioned above. The JWT library supports private keys with the new line character. “\n”.
Add the transform message to create the JWT.
Here, we need to pass the following four parameters to the JWT function.
Sr. No. | Parameter | Datatype | Description | Example |
1 | header | Object | JWT Header | { “alg”: “RS256”, “typ”: “JWT”} |
2 | payload | Object | JWT Payload | { iss: “jwt-rsa-demo@test.com”, aud: ‘https://test.mulesoft.com’, iat: (now()) as Number { unit: ‘seconds’ }, exp: (now() + |PT7200S|) as Number { unit: ‘seconds’ } } |
3 | key | String | RSA private keys. JWT library supports PKCS#1 or PKCS#8 formatted private keys. |
vars.privateKey |
4 | algorithm | String | The supported RSA algorithms are:RS256: Sha256withRSARS384: Sha384withRSARS512: Sha512withRSA | Sha256withRSA |
%dw 2.0
import * from jwt::RSA
output application/json
---
{
token: JWT(
{
"alg": "RS256",
"typ": "JWT"
},
{
iss: "jwt-rsa-demo@test.com",
aud: 'https://test.mulesoft.com',
iat: (now()) as Number { unit: 'seconds' },
exp: (now() + |PT7200S|) as Number { unit: 'seconds' }
},
vars.privateKey as String,
'Sha256withRSA'
),
expiration: (now() + |PT7150S|)
}
Create JWT with HMAC Algorithm
- Add the transform message to create the JWT.
Here, we need to pass the following four parameters to the JWT function.
Sr. No. | Parameter | Datatype | Description | Example |
1 | header | Object | JWT Header | { “alg”: “HS256”, “typ”: “JWT”} |
2 | payload | Object | JWT Payload | { iss: “jwt-hmac-demo@test.com”, aud: ‘https://test.mulesoft.com’, iat: (now()) as Number { unit: ‘seconds’ }, exp: (now() + |PT7200S|) as Number { unit: ‘seconds’ }} |
3 | signingKey | String | Secret Key | “MuleJWTPassword@2023” |
4 | algorithm | String | The supported HMAC algorithms are:HS256: HmacSHA256HS384: HmacSHA384HS512: HmacSHA512 | HmacSHA256 |
%dw 2.0
import * from jwt::HMAC
output application/json
var secretKey = "MuleJWTPassword@2023"
---
{
token: JWT(
{
"alg": "HS256",
"typ": "JWT"
},
{
iss: "jwt-hmac-demo@test.com",
aud: 'https://test.mulesoft.com',
iat: (now()) as Number { unit: 'seconds' },
exp: (now() + |PT7200S|) as Number { unit: 'seconds' }
},
secretKey as String,
'HmacSHA256'
),
expiration: (now() + |PT7150S|)
}
Step 4: Initiate the request, and it will generate the JWT.
JWT with RSA Output:
{
"token": "eyJhbGciOiAiUlMyNTYiLCJ0eXAiOiAiSldUIn0.eyJpc3MiOiAi
and0LXJzYS1kZW1vQHRlc3QuY29tIiwiYXVkIjogImh0dHBz
Oi8vdGVzdC5tdWxlc29mdC5jb20iLCJpYXQiOiAxNjk
2NDkzODQwLCJleHAiOiAxNjk2NDk3NDQwfQ.q50ao
_-1_ke7ZIizZYgz_914q8JcISWk8uCC0h08
FtzlUJYWU0ss7M0gtBJSnDa3e1hAsJ2MlmKhVjL7wXbkY
NRVtdCk6N1RC6dEJ2xLOPKMObvcSHvt9e5sTWO
PqCBW4sZOQm9xMkCqWqkHAJ5wZzvDGOlo7K0I-23b2AhqESD
qVGXNXdWKvgwVGtH1okL7PKy9aQw7grJ
9iB6iV_yaFgGX82gu0m1QilF83VHvAy7sW
q7RYk54FmI09U45-CXYtX_tpaq3Y1vjaGjHmkKqPfJnqO4ysBiRICvxhRcRqQgONqU
Su7YpV59JoUG66r2ONnS9NFJXQSBVq7-GQl0g4A",
"expiration": "2023-10-05T14:46:30.505+05:30"
}
JWT with HMAC Output
{
"token": "eyJhbGciOiAiSFMyNTYiLCJ0eXAiOiAiSldUIn0.
eyJpc3MiOiAiand0LWhtYWMtZGVtb0B0ZXN0LmNvbSIsIm
F1ZCI6ICJodHRwczovL3Rlc3QubXVsZXNvZnQ
uY29tIiwiaWF0IjogMTY5NjQ5MzIzOSwiZ
XhwIjogMTY5NjQ5NjgzOX0.sAiK-Bto_8JS4WLJa3nFoSYCIIv3IiXYLyL0QKXB-hQ",
"expiration": "2023-10-05T14:36:29.62+05:30"
}
Validation
Validate RSA JWT using public key:
Validate HMAC JWT using secret key:
Limitations
The DataWeave JWT Library doesn’t support encrypted private keys for generating JWT using the RSA algorithm. If the requirement is to create a JWT using the RSA algorithm with an encrypted private key, you can use either custom Java code or the JWT Sign Module.
For more details on the JWT Sign Module, you can refer to this article.
References
— By Ujala Kumar Yadav