1. Marcos Bolonha
  2. PowerBuilder
  3. Tuesday, 30 November 2021 15:16 PM UTC

Hi,

I'm developing an integration between Powerbuilder PB 2019R3 application and a Financial API (external of my company) using HTTPClient, but I'm receiving the return error code 403 Forbidden.

// Code

string json, base64, url_api

Integer li_SendReturn

long lr_code

json = '{"grant_type":"client_credentials", "role":"software_house"}'

base64 = 'dXN1YXJpb3Rlc3RlOnNlbmhhdGVzdGU'

url_api = 'https://pix.tecnospeed.com.br/oauth2/token/'

HttpClient http
http = Create HttpClient

// Headers

http.SetRequestHeader("Content-Type", "application/json" )
http.SetRequestHeader("Authorization", "Basic " + base64)
http.SetRequestHeader("cache-control", "no-cache")

li_SendReturn = http.sendrequest('POST', url_api, json)

If http.GetResponseStatusCode() <> 200 Then
MessageBox('','Error: '+string(http.GetResponseStatusCode())+' - '+http.GetResponseStatusText())
end if

/// End

I've tested consuming the API via POSTMAN and it works fine.

Any idea where is my mistake?
Thanks in advanced.

Marcos

 

Mark Lee @Appeon Accepted Answer Pending Moderation
  1. Monday, 13 December 2021 04:59 AM UTC
  2. PowerBuilder
  3. # 1

Hi Marcos,

 

Glad to hear that you got it resolved and thanks for sharing the solution!
PB does support concatenating a variable as used in the authorization header.
Please make sure the variable identificacao is the same as "Basic "+base64.

My verification with the following basic authentication code works fine.

String                    ls_Basic, ls_UserName, ls_Password, ls_Body
Integer         li_Return
CoderObject      lco_Code
HttpClient           lhc_Client
 
lco_Code = Create CoderObject
lhc_Client = Create HttpClient
 
ls_UserName = "guest"
ls_Password = "guest"
ls_Basic = lco_code.base64encode( Blob(ls_UserName + ":" + ls_Password , EncodingUTF8!))
 
lhc_Client.SetRequestHeader( "Authorization", "Basic " + ls_Basic)
li_Return = lhc_Client.SendRequest("GET", "https://jigsaw.w3.org/HTTP/Basic/")
If li_Return = 1 And lhc_Client.GetResponseStatusCode() = 200 Then
                lhc_Client.GetResponseBody(ls_Body)
                MessageBox ("Tips" ,ls_Body )
End If
 
Destroy ( lco_Code )
Destroy ( lhc_Client )
Comment
There are no comments made yet.
Marcos Bolonha Accepted Answer Pending Moderation
  1. Friday, 3 December 2021 01:32 AM UTC
  2. PowerBuilder
  3. # 2

Hi Mark,

I tried your code and the result is the same: error 403 - Forbidden.

Regarding the Postman URL different, I don't have any idea why it changes the URL since I have entered the https://pix.tecnospeed.com.br in its URL address, as you can see on images I've sent before. Maybe the Postman Agent "force" other URL/route to avoid possible erros related to CORS policy.

Attached, the image of fiddler register with APIs request using your suggested code.

I've talked with APIs vendor today and he said that is possible to see on his monitoring application that request method is sending as "OPTIONS" and not as "POST" as we are have entered (li_SendReturn = http.sendrequest('POST', url_api, json)). Could be a bug? Sincerelly I don't beleave that is a bug, but after a lot of hours looking for a solution, I need to include it as a option.


Regards.

Marcos

Attachments (2)
Comment
  1. Mark Lee @Appeon
  2. Friday, 3 December 2021 08:52 AM UTC
Hi Marcos,



Thanks for the confirmation.

Could you provide a screenshot (including the left side of the Fiddler monitor) of the record when you send this request (https://pix.tecnospeed.com.br/oauth2/token) with PostMan?

I’m not sure if this error relates to the CORS policy at this moment but I don’t think "application that request method is sending as "OPTIONS" and not as "POST" as we are have entered (li_SendReturn = http.sendrequest('POST', url_api, json))" is a bug either.

There might be something wrong with the server parsing the data. You can try using the http.sendrequest('OPTIONS', url_api, json) code or http.sendrequest('GET', url_api, json) code and have your APIs vendore help monitor and see if there’s any difference.



Regards,
  1. Helpful
  1. Marcos Bolonha
  2. Saturday, 11 December 2021 18:12 PM UTC
Hi Mark,



After long hours comparing the Postman requests (with and without Postman Desktop Agent) and Powerbuilder requests, Paulo Natal from Dora sistemas in Brazil found a way to avoid the 403 error. The solution has 2 points:



1) First and more important is to add an "User-Agent"="Windows/10" header.

2) The powerbuilder doen't support concatenating a variable when adding defaultheaders to httpclient.



The final code is:



// Code

string json, identificacao

Integer li_SendReturn

long lr_code

json = '{"grant_type":"client_credentials", "role":"software_house"}'

url_api = 'https://pix.tecnospeed.com.br/oauth2/token'



HttpClient http

http = Create HttpClient



identificacao = "Basic "+base64



//Headers

http.ClearRequestHeaders()

http.SetRequestHeader("Accept-Charset", "utf-8" )

http.SetRequestHeader("Accept-Language", "en,zh" )

http.SetRequestHeader("Cache-Control", "no-cache")

http.SetRequestHeader("Content-Type", "application/json" )



// http.SetRequestHeader("Authorization", "Basic "+base64) <<== PB doesn't accept concatenate when adding headers

http.SetRequestHeader("Authorization", identificacao) // This is accepted by PB and works fine



// Header added for avoid 403 error //

http.SetRequestHeader("User-Agent", "windows/10")



li_SendReturn = http.sendrequest('POST', url_api, json)



Special thanks for Paulo Natal from Dora Sistemas, our PB support in Brazil that didn't save efforts the find a solution.



Best regards.



Marcos

  1. Helpful
  1. Armeen Mazda @Appeon
  2. Saturday, 11 December 2021 18:22 PM UTC
Thanks for sharing the solution!
  1. Helpful
There are no comments made yet.
Mark Lee @Appeon Accepted Answer Pending Moderation
  1. Thursday, 2 December 2021 06:25 AM UTC
  2. PowerBuilder
  3. # 3

Hi Marcos,

 

I referred to the information you provided and got the same test results as Daryld’s in PostMan and PowerBuilder.

If you are sure that your PostMan settings are the same as mine, but you can pass the test, you can try the PB code I provide to verify if it still returns a 403 error?

PB Code

// Code

string json, base64, url_api

Integer li_SendReturn

long lr_code

json = '{"grant_type":"client_credentials", "role":"software_house"}'

//base64 = 'dXN1YXJpb3Rlc3RlOnNlbmhhdGVzdGU'
base64 ='bwFyY29zQHNvZnRjb25pbmZvcm1hdGljYS5jb20uYnI6UzBmdGMwbi4xOTk3'

url_api = 'https://pix.tecnospeed.com.br/oauth2/token'
//url_api = 'https://pix.tecnospeed.com.br/v1/request'

HttpClient http
http = Create HttpClient

// Headers

http.SetRequestHeader("Content-Type", "application/json" )
http.SetRequestHeader("Accept-Encoding", "gzip,deflate,br")
http.SetRequestHeader("Connection", "keep-alive")
http.SetRequestHeader("Authorization", "Basic " + base64)
http.SetRequestHeader("cache-control", "no-cache")
//http.SetRequestHeader("Content-Length", string(len(json)))
//

li_SendReturn = http.sendrequest('POST', url_api, json)

If http.GetResponseStatusCode() <> 200 Then
	MessageBox('','Error: '+string(http.GetResponseStatusCode())+' - '+http.GetResponseStatusText())
end if

/// End

 

Also, from those Fiddler screenshots, it looks like postman is calling a different URL (/v1/request) while Powerbuilder is calling /oauth/token/.

I guess your API request address may be different. Can you provide the Host address shown on the left side of the screenshot of the Fiddler? Is it https://pix.tecnospeed.com.br?

 

Regards,

Comment
There are no comments made yet.
Marcos Bolonha Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 21:50 PM UTC
  2. PowerBuilder
  3. # 4

Hi Daryl,

Thanks for replying.

The screenshots as you said:

The Postman Headers:

The Postman Authorization

The Postman Body

Comment
  1. Daryl Foster
  2. Wednesday, 1 December 2021 23:38 PM UTC
Thanks Marcos,



I get the 403 Forbidden error when I try from Postman and Powerbuilder. Could the API be restricted to certain IP Addresses? Does it work for you in Postman from the same machine that it fails from in Powerbuilder?

Has the API vendor given you any documentation about accessing the API?



One thing I did note, but it may not make any difference, is that your url in Powerbuilder has a trailing forward slash (url_api = 'https://pix.tecnospeed.com.br/oauth2/token/'), it probably only needs to be url_api = 'https://pix.tecnospeed.com.br/oauth2/token'
  1. Helpful
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 19:00 PM UTC
  2. PowerBuilder
  3. # 5

Hi Marcos, can you also post screen shots of your Postman request that generated that Fiddler output showing the Body, Headers and Authorization tabs?

From those Fiddler screen shots it looks like postman is calling a different URL (/v1/request) while Powerbuilder is calling /oauth/token/.  So I’m interested in seeing what you have entered in Postman to generate that request.

Comment
There are no comments made yet.
Marcos Bolonha Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 18:23 PM UTC
  2. PowerBuilder
  3. # 6

I just tried to consume the API via Postman (web browser) from another computer and it didn't work. So, the Postmand asked me to use Postman Desktop Agent, as the image shows and after agent installation it is working fine. It seems that the Postman needs to use some additional resource for consuming that API.

Comment
There are no comments made yet.
Marcos Bolonha Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 18:23 PM UTC
  2. PowerBuilder
  3. # 7

I just tried to consume the API via Postman (web browser) from another computer and it didn't work. So, the Postmand asked me to use Postman Desktop Agent, as the image shows and after agent installation it is working fine. It seems that the Postman needs to use some additional resource for consuming that API.

Comment
There are no comments made yet.
Marcos Bolonha Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 14:11 PM UTC
  2. PowerBuilder
  3. # 8

Hi Mark Lee and Daryl Foster.

The screenshots and TXT file with the request/response headers.  I'm not able to understand the difference between them because they are completely different. Also, HTTP is not my strong point.

The screenshot of fiddler of Powerbuilder request:

and the screenshot of Postman request:

Comment
  1. Marcos Bolonha
  2. Wednesday, 1 December 2021 17:56 PM UTC
Hi,



I was researching on internet and found some discussions related "CORS policy". Considering the API as out of my company, there is any way to avoid CORS policy error in Powerbuilder application?



I'm not sure if it could be the cause of this issue...



Marcos
  1. Helpful
There are no comments made yet.
Mark Lee @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 07:00 AM UTC
  2. PowerBuilder
  3. # 9

Hi Marcos,

 

As Daryl suggested, please share some screenshots of the Postman call that works for you showing the URL, headers and body.

 

In the meantime, please make sure that you have set the HTTP request header in your PB code to the same as that in your Postaman test.

You can also download a tool like Fiddler to monitor all data it sends and receives to find the differences between the data sent between Postman and PB HTTPClient object, which could help you resolve the issue.

 

Regards,

Comment
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Wednesday, 1 December 2021 00:03 AM UTC
  2. PowerBuilder
  3. # 10

Hi Marcos,

Have you got screenshots of the Postman call that works for you showing the URL, headers and body?  Maybe something will stand out if we can see that.

Comment
There are no comments made yet.
Marcos Bolonha Accepted Answer Pending Moderation
  1. Tuesday, 30 November 2021 21:38 PM UTC
  2. PowerBuilder
  3. # 11

Hi Alex,

Thanks for replying. I just tried, but the return code is the same: 403 - Forbidden.

Regards.

Marcos

 

Comment
There are no comments made yet.
Alex Riofrio Accepted Answer Pending Moderation
  1. Tuesday, 30 November 2021 17:48 PM UTC
  2. PowerBuilder
  3. # 12

Hi Marcos;

Why don't you try with the RESTClient object and use SetJwtToken function to set the token string to the HTTP request header.

Here an example.

Alex.

 

String ls_P028_JWTToken
Integer li_P028_GetJWTTokenReturn
RestClient lrc_P028
lrc_P028 = Create RestClient

lrc_P028.SetRequestHeaders( "Content-Type:application/json;charset=UTF-8~r~nAccept-Encoding:gzip" ) //Sets the request header
//Gets the JWT token. The second parameter provides the value according to the token server request.
li_P028_GetJWTTokenReturn=lrc_P028.GetJWTToken("https://demo.appeon.com/pb/jwt/HSExample/api/values/GetToken", '{"Username":"user1","Password":"password1"}', ls_P028_JWTToken)

If li_P028_GetJWTTokenReturn = 1 Then
 //Sets the JWT token
 lrc_P028.SetJwtToken( ls_P028_JWTToken)
 //Retrieves data for dw_Data
 lrc_P028.retrieve( dw_Data, "https://demo.appeon.com/pb/jwt/HSExample/api/department/retrieve")
Else
 //Prints the GetJWTToken error message if any
End If
Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.