Title: MDRTOKEN Copybook Date: 2024-07-03
MDRTOKEN COPYBOOK
This copybook is supplied with the MDRest4i Product. It can be found in MDRST/QRPGLESRC. It contains the templates and ILE procedures available in the MDRTOKEN service program.
Example Program
Please see MDRST/EXAMPLE.MDRTKNAPI for an example REST API program. This program demonstrates how to call the various available MDRTOKEN functions.
MDRDCRED_t MDRDCRED template
This is a data structure template based on table MDRDCRED:
Subfield | Description |
---|---|
clientid | Client ID - can be any value used to identify this credential |
appid | Application ID- can be any value used to identify this credential |
usetyp | Usage Type - A=API, C=Consumer, B=Both, O=Other |
credtyp | Credential Type - B=Basic, T=Bearer(Token) R=Remote |
tkntyp | Token Type: PAT= Personal Access Token, JWT=JSON Web Token, JWS=JSON Web Signature |
algor | Encryption/Decryption Algorithm & Key type: UUID = Random 36 byte value HS256 = Secret and SHA256 Encryption for Signature RS256-DCM = RS256 using DCM App RS256-KST = RS256 using PF and Lib Key Store RS256-PVT = RS256 using Private & Public Keys |
authtoken | Authentication Token |
username | User Name - usually used in consumers to obtain token |
passwd | Password - usually used in consumers to obtain token |
payload | JSON payload for JWT Claims or JWS body as JSON string |
dcmapp | DCM Application used for signatures |
keystore | Path to keystore |
keystuser | Keystore user |
keystpwd | Keystore password |
cliSecret | Client Secret |
publickey | Public key used for jwtalgo=RS256-PVT |
privatekey | Private key used for jwtalgo=RS256-PVT |
autsvr | URI used to validate token |
toksvr | URI used to get new, or refresh token |
refreshmth | Refresh Method - Automatic or Manual |
refreshtkn | Token used to refresh expired token |
atokenexp | authToken Token Expiry period |
rtokenexp | refreshtkn Token Expiry period |
claimsiat | "iat" value from claims payload |
claimsExp | "exp" value from claims payload |
expiryunit | Unit of measure used for Auth/Refresh token expiry |
issuer | username of person who created token |
issuetime | Issued timestamp |
issueLog | Issue User/Jobname/jobnumber etc |
updatetime | MDRDCRED Record update timestamp |
updatelog | Update User/Jobname/jobnumber etc |
dcl-ds MDRDCRED_t qualified template;
clientid varchar(36) ;
appid varchar(20) ;
usetyp char(1) ;
credtyp char(1) ;
tkntyp char(3) ;
algor varchar(20) ;
authtoken varchar(4096);
username varchar(256) ;
passwd varchar(1024) ;
claims varchar(1024);
dcmapp varchar(50) ;
keystore varchar(256) ;
keystuser varchar(256) ;
keystpwd varchar(256) ;
clisecret varchar(2048) ;
publickey varchar(2048) ;
privatekey varchar(2048);
autsvr varchar(2048) ;
toksvr varchar(2048) ;
refreshmth char(10) ;
refreshtkn varchar(4096) ;
atokenexp int(10) ;
rtokenexp int(10) ;
claimsiat int(10) ;
claimsexp int(10) ;
expiryunit char(10) ;
issuer char(36) ;
issuetime timestamp ;
issuelog char(64) ;
updatetime timestamp ;
updatelog char(64) ;
end-ds;
MDR_claims_t
This is a data structures template used to contain key/value pairs for a JWT Token:
MDR_createToken
Creates a auth and refresh token and saves details in MDRDCRED as requested
Note
see MDRST/QRPGLESRC.MDRTKNAPI for an example how to use this function.
see https://wiki.midrangedynamics.com/manuals/MDRest4i/manual/create-rs256-token/ for adetailed help on how to create an RS256 JWT token
@param (input/output) creds = credentials data structure
@param (outout) errMsg = any error messages from creation
@param (input) save = *ON=save, *OFF=don't save, details to MDRDCRED
Note: if not passed this is set to *ON by default
@return *ON if created/saved, *OFF if failed```
dcl-pr MDR_createToken ind;
creds likeds(MDRDCRED_t);
errMsg varchar(200);
save ind const options(*nopass);
end-pr;
Token Validation Constants
dcl-c c_VALID const('V');
dcl-c c_INVALID const('I');
dcl-c c_NOTFOUND const('N');
dcl-c c_EXPIRED const('E');
dcl-c c_INVALIDSIGN const('S');
MDR_validateToken
Validates a token. The third parameter is optional and if supplied, the second part of the token (i.e. claims payload) is decoded from base64 back to JSON string, parsed and the JSON key/value pairs loaded in this data structure parameter
- Check if the token is valid and has three values separated by dots
- Check if the token exists in MDRDCRED database
- Check if the auth token is valid by comparing current timestamp with the value in claimsIat and doesn't exceed MDRDCRED.claimsexp
- Extract the claims from the JWT claims section of te token, and return JSON key/value pairs in third data structure parameter
@param (input) authToken = auth token for validation
@param (output) errMsg = any error messages from creation
Possible messages: Token not found in database
Token expired
Token signature invalid
@param (output) tknClaims = array of key/value pairs of the JWT token claims.
@return V=Valid, N=Not found, E=Expired, S=Invalid Signature
dcl-pr MDR_validateToken char(1);
authToken varchar(4096);
errMsg varchar(200);
tknClaims dim(20) likeds(MDR_tknClaims_t) options(*nopass);
end-pr;
MDR_validateAuthToken
Retrieves the auth token from the API request via cgi channel and then it calls MDR_ValidateToken to validate the token. The fourth parameter is optional and if supplied, the second part of the token (i.e. claims payload) is decoded from base64 back to JSON string, parsed and the JWT claims JSON key/value pairs loaded in this data structure. See MDR_tknClaims_t for details.
@param (input) handle: threadsafe handler key
@param (output) authToken = auth token as retrieved from API and validated
@param (output) errMsg = any error messages from creation
Possible messages: Token not found in database
Token expired
Token signature invalid
@param (output) tknClaims = array of key/value pairs of the JWT token claims.
@return V=Valid, N=Not found, E=Expired, S=Invalid Signature,
X=Not a bearer token
Status = MDR_validateAuthToken(handle:authToken:erorrMsg) or
Status = MDR_validateAuthToken(handle:authToken:erorrMsg:tknClaimsDS)
dcl-pr MDR_validateAuthToken char(1);
handle like(MDR_Handle_t);
authToken varchar(4096);
errMsg varchar(200);
tknClaims dim(20) likeds(MDR_tknClaims_t) options(*nopass);
end-pr;
MDR_refreshToken
Refreshes the auth token and saves details in MDRDCRED
Note
Only the refresh token is required to be supplied in the "creds" data structure and rest all fields can be sent as blank/zeros. After the procedure call, the data structure "creds" will have all the values loaded from the MDRDCRED credentials file with the new auth/refresh token
@param (input/output) creds = credentials data structure but only the refresh
token from the DS is used
@param (outout) errMsg = any error messsages from refresh
@param (input) save = *ON=save, *OFF=don't save, details to MDRDCRED
Note: if not passed this is set to *On by default
@return *ON if refreshed/saved, *OFF if failed
dcl-pr MDR_refreshToken ind;
creds likeds(MDRDCRED_t);
errMsg varchar(200);
save ind const options(*nopass);
end-pr;
MDR_verifySign
Verifies the token signature provided and returns status. The procedure reads the credentials DB file to find the DCM application or client secret depending on the algorithm along with other details to recreate the signature and then match with the third part of the token
// Note: This procedure accepts "creds" data structure but only "authToken" is used
@param (input/output) creds = credentials data structure @param (output) errMsg = any error messsages from validation
@return V=Valid, N=Not found, S=Token Invalid Signature
Example:
MDR_deleteToken
Deletes the MDRCRED credentials record for clientid, appid or the auth token
NOTE: Only the auth token or "clientId" and "appId" is required to be supplied in "creds" data structure.
@param (input/output) creds = credentials data structure @param (outout) errMsg = any error messages from creation
@return ON if deleted, OFF if delete failed
Example:
MDR_CalculateNewEpochTime
Calculate Epoch time time from given epoch time, duration and time unit
@param (input) epochTime = Base value of epoch Time @param (input) duration = duration to add to epoch time @param (input) timeUnit = e.g. SECONDS or S, MINUTES or M HOURS or H, DAYS or D
@return new value in epochtimestamp
Example: newEpochTimeStamp = MDR_CalculateNewEpochTime(inputEpochTime:ValueToAdd:'*SECONDS')
dcl-pr MDR_CalculateNewEpochTime int(20);
epochTime int(20) const;
duration int(10) value;
timeUnit char(10) const;
end-pr;
MDR_CvtToEpochTimestamp
Convert supplied timestamp to Epoch time
@param (input) timeStampVal = timestamp value requested for conversion
@return epoch timestamp
Example: newEpochTimeStamp = MDR_CalculateNewEpochTime(timeStampValue)
MDR_getClaims
Parse the claims payload and return key/value pairs in an array
@param (input) jsonClaims = JSON string to be parsed for key/value pairs @param (output) tknClaims = data structure array containing json key/values
Example: MDR_getClaims(claimsPayload:claims_ds)
MDR_createJWT_RS256_DCM
Creates a JWT Token using RS256-DCM algorithm from request JSON body. Returns *ON if OK, plus tokenResp ds with the token details
@param (input) handle: threadsafe handler key @param (input) body = request JSON body @param (input/output) creds = details to create/save Token @param (output) tokenResp = created token response ds @param (output) errorMsg = error message (if any) @param (input) save = option to save token to MDRDCRED
@return indicator *ON if successful
Example JWT Claim Payloads
Below are two example payloads that can be used to generate JWT tokens, using RS256 Algorithm with public and private keys from the IBM i DCM:
Here is the prototype: