​
Hi, I too was stuck on this for a day, but figured it out
I've attached the code to generate the token using the JWT Secret
To generate the token you may need additional information in the PayloadJSONObject like
Issuer:
Subject:
JTI: <I'm assuming this is a user id or something similar>
procedure CreateJWT(PayloadJsonInfo: JsonObject; SignKey: Text; ExpireInSeconds: Integer) JWTToken: Text;
var
CryptographyMgt: Codeunit "Cryptography Management";
Base64Convert: Codeunit "Base64 Convert";
Header, PayLoad, Signature, SignatureHashInput : Text;
IssuedAtLbl: Label 'iat', Locked = true;
ExpireLbl: Label 'exp', Locked = true;
Algorithm: Text;
HeaderJson: JsonObject;
txtHeaderBuilder: TextBuilder;
TxtBuilder: TextBuilder;
HeaderAlgLbl: Label 'alg', Locked = true;
HeaderTypLbl: Label 'typ', Locked = true;
HashAlgorithmType: Option HMACMD5,HMACSHA1,HMACSHA256,HMACSHA384,HMACSHA512;
begin
Algorithm := 'HS256'; // Using HMAC SHA256
// 1. Add timestamps to the payload
PayloadJsonInfo.Add(IssuedAtLbl, Format(GetCurrentDateTimeAsUnixTimeStamp()));
PayloadJsonInfo.Add(ExpireLbl, Format(GetCurrentDateTimeAsUnixTimeStamp() + (ExpireInSeconds * 1000)));
// 2. Setup and encode the header
HeaderJson.Add(HeaderAlgLbl, Algorithm);
HeaderJson.Add(HeaderTypLbl, 'JWT');
HeaderJson.WriteTo(Header);
Header := Base64UrlEncode(Base64Convert.ToBase64Url(Header));
// 3. Encode the payload
PayloadJsonInfo.WriteTo(PayLoad);
PayLoad := Base64UrlEncode(Base64Convert.ToBase64Url(PayLoad));
// 4. Create the signature hash input (encoded header + "." + encoded payload)
SignatureHashInput := Header + '.' + PayLoad;
// 5. Generate the signature using the secret key and SHA256
// Note: The key should be handled as SecretText in a production environment for security
Signature := CryptographyMgt.GenerateBase64KeyedHashAsBase64String(SignatureHashInput, SignKey, HashAlgorithmType::HMACSHA256); // Using HMAC SHA256
// 6. URL-safe Base64 encode the signature and combine for the final JWT
Signature := Base64UrlEncode(Signature);
JWTToken := SignatureHashInput + '.' + Signature;
end;
// Helper function to get current Unix timestamp
local procedure GetCurrentDateTimeAsUnixTimeStamp(): BigInteger;
var
UnixtimeStamp: Codeunit "Unix Timestamp";
begin
exit(UnixtimeStamp.CreateTimestampMilliseconds((CreateDateTime(Today, Time))));
end;
// Helper function for URL-safe Base64 encoding (removes padding, replaces specific chars)
local procedure Base64UrlEncode(Input: Text): Text;
begin
// Remove '=' padding and replace '+' with '-', '/' with '_'
exit(Input.Replace('=', '').Replace('/', '_').Replace('+', '-'));
end;
I haven't done it using User Id and Password. I hope this helps.
​