HTTP_POINT_ADDL_HEADER Header parameters

Discussions related to HTTPAPI (An HTTP Client Package for RPG programming.) http://www.scottklement.com/httpapi/
Post Reply
twisteddisco
Posts: 6
Joined: Thu Dec 12, 2024 9:05 pm

HTTP_POINT_ADDL_HEADER Header parameters

Post by twisteddisco »

Hello All,

Question on the HTTP_POINT_ADDL_HEADER routine.

I have a requirement where I need to create a webservice which will include HEADER parameters and a REQUEST body.

The HEADER parameters are:
IvUserKey
ivUserBic

The Request Body parameters are:
party
partyAccount

I have never used HTTPAPI to add header parameters, looking at existing posts I think I need to do something like this using

Code: Select all

   
// Notify httpapi of the routine to use to add headers
http_xproc( HTTP_POINT_ADDL_HEADER: %paddr(AddHeaders));

// --------------------------------------------------                    
// Perform the http request and get back the response                    
// --------------------------------------------------                    
Monitor;                                                                 
wResponse = http_string('POST': wUrl: eJsonString: 'application/json'); 

dcl-proc AddHeaders;
  dcl-pi *n;
    toBeAdded varchar(32767);
  end-pi;

  toBeAdded = 'IvUserKey: valuea' + x'0d25'
     		   + 'ivUserBic: valueb' + x'0d25';
 end-proc;
 
Is this the correct way to go about this?

Thankyou for your time, much appreciated
Scott Klement
Site Admin
Posts: 909
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP_POINT_ADDL_HEADER Header parameters

Post by Scott Klement »

It looks correct to me.
sathis_nsk
Posts: 1
Joined: Fri May 03, 2024 10:45 am

Re: HTTP_POINT_ADDL_HEADER Header parameters

Post by sathis_nsk »

Just an additional info.

I used the following statement to register a header handler:

Code: Select all

http_xproc( HTTP_POINT_ADDL_HEADER  : %paddr(Add_headers) ); 
However, I noticed that subsequent HTTP requests to different endpoints (such as the authentication token request) within the same program continued to carry over the same headers.

To resolve this, I had to explicitly deregister the header handler after each HTTP request by using:

Code: Select all

http_xproc( HTTP_POINT_ADDL_HEADER  : *NULL );                
Scott Klement
Site Admin
Posts: 909
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP_POINT_ADDL_HEADER Header parameters

Post by Scott Klement »

Yes, that is the expected behavior.
twisteddisco
Posts: 6
Joined: Thu Dec 12, 2024 9:05 pm

Re: HTTP_POINT_ADDL_HEADER Header parameters

Post by twisteddisco »

It seems my authorisation header needs to be in BASE64, for this I have downloaded Scott's BASE64R4 program.

The program BASE64R4 makes perfect sense (Thanks Scott) but I just wondered about the format of the data when I add it to header, once converted does it still need the CRLF at the end?

For example:
My details are:

User Id: demo
Password: p@55w0rd

When encoded to BASE64 this looks like ZGVtbzpwQDU1dzByZA==

The format of the authorization header should be Authorization: Basic ZGVtbzpwQDU1dzByZA==
Scott Klement
Site Admin
Posts: 909
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP_POINT_ADDL_HEADER Header parameters

Post by Scott Klement »

Support for that is built-in. Just do this before your request:

Code: Select all

http_setauth(http_auth_basic : 'demo' : 'p@55w0rd' );
...http_string...and other code here...

After you are done, remove the password from memory...

Code: Select all

http_setauth(http_auth_none:'':'');
twisteddisco
Posts: 6
Joined: Thu Dec 12, 2024 9:05 pm

Passing JWT in Request Body

Post by twisteddisco »

Hi All,

First of all thankyou for your help now and in the past, much appreciated.

The requirements for my program have move on slightly.
Authorization Header
Your application credentials, client_id and client-secret of the app you created, are exchanged through the Basic Authentication Scheme in the authorization header. Calculate the base-64 encoded value of client_Id:client_secret and use it in the authorization header with the keyword Basic in front of it.
Request Body
Depending on the data sensitivity behind the APIs you are trying to access, you will be applying one of the two authorisation grant types: Password Grant Type or JWT Bearer Grant Type. We need JWT Bearer Grant Type
For APIs using JWT Bearer grant type, you must generate a JSON Web Token (JWT) using your Swift-issued PKI certificates.
Parameters Values Descriptions
grant_type urn:ietf:params:oauth:grant-type:jwt-bearer Use the value as is.
scope RBAC role/qualifiers example xxx.xxxx,api!p
assertion Signed JSON Web Token This value is the signed JWT containing the claims and signed by your channel certificate
To achieve the creation of the JWT I have a new program based on the findings in the following URL:
This creates a long base64 encoded string that does validate in JTW.IO so I am fairly happy this is correct, more on this later...

When I then process this in the program it the code looks as follows:

Code: Select all

//█Set Options                           
http_setOption('timeout': '30');         
http_setOption('network-ccsid': '1208' );
http_use_cookies(*OFF);                  

tokenendpoint = %Trim(wAuthUrl);                              
resultStr         = *Blanks;                                      
GrantType       = 'urn:ietf:params:oauth:grant-type:jwt-bearer';

http_setAuth( HTTP_AUTH_BASIC         
            : %trim(client_id)        
            : %trim(client_secret) ); 
            
sendData = 'grant_type=' + %trimr(http_urlEncode(%trimr(GrantType))) +    
                  '&scope='+ %trimr(http_urlEncode(%trimr(wScope)))       +      
                  '&assertion=' +%trimr(JsonWebToken);                                                  

Code: Select all

rc = http_req( 'POST'                   // Type                           
              : tokenendpoint            // Url                            
              : *omit                          // Result Stmf                    
              : resultStr                     // String to receive the results  
              : *omit                          // Send Stmf                      
              : sendData                    // Send String                    
              : 'application/x-www-form-urlencoded'); // Content          
When the program runs under debug I can see the following values:

Code: Select all

SENDDATA =                                                             
          ....5...10...15...20...25...30...35...40...45...50...55...60 
     1   'grant_type=urn%3Aietf%3Aparams%3Aoaut&scope=eba.step2.api!p&'
    61   'assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsIng1YyI6WyJNSU'
   121   'lFeGpDQ0FxNmdBd0lCQWdJRWFLcDIwVEFOQmdrcWhraUc5dzBCQVFzRkFEQV'
   181   'FNUTR3REFZRFZRUUtFd1ZUVjBsR1ZEQWVGdzB5TlRBNE1qZ3hNek0wTVRaYU'
   241   'Z3MHlOekE0TWpneE5EQTBNVFphTUVZeERqQU1CZ05WQkFvVEJYTjNhV1owTV'
   301   'JFd0R3WURWUVFLRXdobGJtbGlZbVZpWWpFT01Bd0dBMVVFQ3hNRmMzUmxjRE'
grant_type seems to be urlencoded correctly!
scope also seems to be urlencoded correctly!

So the result back from the call is as follows:
2025-09-04-11.09.12.255703: recvdoc(): Receiving 141 bytes.
{ "error":"invalid_request", "error_description":"OAuth token grant request is malformed." }
2025-09-04-11.09.12.255736: recvdoc(): have 141 of 141
2025-09-04-11.09.12.255756: SetError() £13: HTTP/1.1 400 Bad Request
I believe the malformed Oauth token grant request is caused by certain information in the JWT not being correct, such has fields in the payload body. These will be clarified by the API provider

I have written previous webservices to get OAUTH2 using user and password but none that need to pass a JWT.

Does the code above look correct or am I missing something?
Scott Klement
Site Admin
Posts: 909
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP_POINT_ADDL_HEADER Header parameters

Post by Scott Klement »

I'm not familiar with using a JWT this way. You'll need to consult the documentation for the authorization server you are communicating with.
Post Reply