HTTP Authentication help

Discussions related to HTTPAPI (An HTTP Client Package for RPG programming.) http://www.scottklement.com/httpapi/
Post Reply
giuliocarlomagno
Posts: 7
Joined: Sat Sep 10, 2022 3:59 pm

HTTP Authentication help

Post by giuliocarlomagno »

Hi all. I don't have many experience with http post.
Can someone please help ?

Here the execution with CURL and it work fine.

curl -X 'PUT' \
'https://xx-xxxx.xxx-xxxxxx.it/xxxxxxx/1 ... xxxxxxxxxx' \
-H 'accept: */*' \
-H 'Authorization: Basic omissisvaWxzOkhmOMISSISOMISSIS==' \
-H 'Content-Type: application/json' \
-d '{omissis}'

Here my rpg call:
.
H DFTACTGRP(*NO) ACTGRP(*NEW) BNDDIR('HTTPAPI')

D/copy qrpglesrc,httpapi_h

D incoming PR 10I 0
D descriptor 10I 0 value
D data 8192A options(*varsize)
D datalen 10I 0 value

D rc s 10I 0
D msg s 52A

D data S 2048A
*
D retdata S 32766A
D retlen S 10I 0
D nextpos S 10I 0 inz(1)
.
.

http_xproc( HTTP_POINT_ADDL_HEADER
: %paddr(add_headers) );

rc = http_url_post_raw('https://xx-xxxx.xxx-xxxxxx.it/'+
'xxxxxxx/1.1.0/xxxxxxxxxxxxx'
: %addr(data)
: %len(%trimr(data))
: 1
: %paddr('INCOMING')
: 30
: HTTP_USERAGENT
: 'application/json');


RET_VALUE = http_error; that contain "This page requires a user-id & password"

http_xproc(HTTP_POINT_ADDL_HEADER: *null);

.
.
.
i Think the problem is here.
.
P add_headers B
D PI
D headers 32767a varying
D CRLF C x'0d25'
D token s 1024a varying
/free
// code to calculate 'token' should go here.
token = 'omissis==';
headers = 'Authorization: Basic' + token + CRLF;
/end-free
P E
giuliocarlomagno
Posts: 7
Joined: Sat Sep 10, 2022 3:59 pm

Re: HTTP Authentication help

Post by giuliocarlomagno »

I have solved the previous isuue but now get another error.

SetError() £13: HTTP/1.1 405 Method Not Allowed

-------------------------------------------------------------------------------------
HTTPAPI Ver 1.23 released 2008-04-24
OS/400 Ver V7R3M0

New iconv() objects set, PostRem=819. PostLoc=0. ProtRem=819. ProtLoc=0
http_setauth(): entered
http_persist_open(): entered
http_long_ParseURL(): entered
DNS resolver retrans: 2
DNS resolver retry : 2
DNS resolver options: x'00000136'
DNS default domain: XXXXX.XXXXX
DNS server found: XX.XXX.XX.XX
https_init(): entered
-------------------------------------------------------------------------------------
Dump of local-side certificate information:
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
Dump of server-side certificate information:
-------------------------------------------------------------------------------------
Cert Validation Code = 6000
-----BEGIN CERTIFICATE-----
OMISSIS
-----END CERTIFICATE-----
Serial Number: OMISSIS
Common Name: *.XXX-XXXXXX.it
Issuer CN: omissis
Issuer Country: XX
Issuer State/Province: XXXXXX
Issuer Locality: XXXXXXX
Issuer Org: XXXXXXX
Issuer Org Unit: http://XXX.XXXXXX.com/repository/
Version: 3
not before: 20210915161819
Unknown Field: 16:18:19 15-09-2021
not after: 20221007174638
Unknown Field: 17:46:38 07-10-2022
pub key alg: OMISSIS
signature algorithm: OMISSIS

SetError() £49: SSL_protocol: Unknown protocol 596
Protocol Used:
http_persist_post(): entered
http_long_ParseURL(): entered
do_post(): entered
POST /omisssis/1.1.0/omissis HTTP/1.1
Host: OMISSIS
User-Agent: http-api/1.23
Content-Type: application/json
SOAPAction: PUT
Expect: 100-continue
Content-Length: 536
Authorization: Basic omissis

recvresp(): entered
HTTP/1.1 100 Continue

SetError() £13: HTTP/1.1 100 Continue
senddoc(): entered
{omissis}
recvresp(): entered
HTTP/1.1 405 Method Not Allowed
Date: Sat, 10 Sep 2022 19:47:27 GMT
Server: WebServer
Strict-Transport-Security: max-age=3600; includeSubdomains;
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,DELETE,PUT
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Content-Type,Authorization
Content-Type: application/json;charset=utf-8
Access-Control-Expose-Headers: ErrorMessage
ErrorMessage: Unknown method: POST
Content-Length: 0
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-control: no-store, no-cache
X-Frame-Options: deny

SetError() £13: HTTP/1.1 405 Method Not Allowed
recvdoc parms: identity 0
header_load_cookies() entered
recvdoc(): entered
SetError() £0:
SetError() £13: HTTP/1.1 405 Method Not Allowed
http_close(): entered
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP Authentication help

Post by Scott Klement »

Hello Giuliocarlo,

That is a very old version of HTTPAPI. Please consider updating to the current version. I cannot support 14 year old versions of HTTPAPI.

With regards to the error, this API does not support the POST method -- therefore you get "405 Method Not Allowed".

In your CURL example, you are using the PUT method. Can you explain why you changed it to POST for HTTPAPI? Also, you seem to have set the SOAP Action to PUT -- which does not make sense since this is not a SOAP transaction. I think you are confused about what what these things are.

Explanation: An HTTP method is similar to an RPG operation code. Just as you might do a OPEN, CLOSE, READ, WRITE or UPDATE in RPG to tell it what to do with the data, in the HTTP network protocol, you must tell it what to do with your data (including the URL) and you must do that with an HTTP method.

The most common HTTP methods are GET, POST, PUT, DELETE and HEAD.

In the old versions of HTTPAPI, you specified the method by which subprocdure you call. So the old http_url_post_raw() procedure always does the POST method... that's why it's called "http_url_post_raw" instead of something else. (There is also an http_url_get_raw if you prefer to use the GET method.) Back in the time when these routines were written, GET and POST were the only methods that most systems supported, so only those methods work with the http_url_XXXX subprocedures.

In newer versions of HTTPAPI (Since 2017 -- so 5 years ago) there are easier to use routines such as http_req(), http_stmf() and http_string(). These accept the HTTP method as a parameter, so can be used with any method.

Also, I see that you've coded your own routine for Basic Authentication. While that's possible (and you seem to have it working), I would discourage it -- please consider using the built-in routine http_setAuth() in HTTPAPI unless you need a special feature that it doesn't support.

Code: Select all

http_setAuth(HTTP_AUTH_BASIC: 'userid-here': 'password-here');

http_setOption('timeout': '30');          // Timeout after 30 seconds
http_setOption('network-ccsid': '1208');  // Expect data to be UTF-8

rc = http_req( 'PUT'
             : 'https://xx-xxxx.xxx-xxxxxx.it/xxxxxxx/1.1.0/xxxxxxxxxxxxx'
             : *omit
             : ResultString     // String to receive the results
             : *omit
             : %trimr(data)
             : 'application/json');
giuliocarlomagno
Posts: 7
Joined: Sat Sep 10, 2022 3:59 pm

Re: HTTP Authentication help

Post by giuliocarlomagno »

Thank you Scott. I proceed to upgrade HTTPAPI at last version.
BR
Giulio Carlomagno
giuliocarlomagno
Posts: 7
Joined: Sat Sep 10, 2022 3:59 pm

Re: HTTP Authentication help

Post by giuliocarlomagno »

Hi all and thank you Scott.
After LIBHTTP upgrade to last versio, now all work fine.

-------------------------
HTTPAPI Ver 1.45 released 2021-09-20
NTLM Ver 1.4.0 released 2014-12-22
OS/400 Ver V7R3M0

New iconv() objects set, PostRem=819. PostLoc=0. ProtRem=819. ProtLoc=0
http_setauth(): entered
New iconv() objects set, PostRem=1208. PostLoc=0. ProtRem=819. ProtLoc=0
http_persist_open(): entered
http_long_ParseURL(): entered
DNS resolver retrans: 2
DNS resolver retry : 2
DNS resolver options: x'00000136'
DNS default domain: XXXXX.local
DNS server found: XX.XXX.XX.XX
https_init(): entered
QSSLPCL = *OPSYS
SSL version 2 support disabled
SSL version 3 support disabled
Old interface to TLS version 1.0 support enabled
TLS version 1.0 support enabled
TLS version 1.1 support enabled
TLS version 1.2 support enabled
Support for TLS 1.3 unavailable.
initializing GSK environment
GSK Environment now available
-------------------------------------------------------------------------------------
Dump of local-side certificate information:
-------------------------------------------------------------------------------------
Nagle's algorithm (TCP_NODELAY) disabled.
SNI hostname set to: xx-xxxx.xxx-xxxxxx.xx
-------------------------------------------------------------------------------------
Dump of server-side certificate information:
-------------------------------------------------------------------------------------
Cert Validation Code = 6000
-----BEGIN CERTIFICATE-----
omissis
-----END CERTIFICATE-----

Omissis

Protocol Used: TLS Version 1.2
http_persist_req(PUT) entered.
http_long_ParseURL(): entered
http_long_ParseURL(): entered
do_oper(PUT): entered
There are 0 cookies in the cache
PUT /omissis/ HTTP/1.1
Host: omissis
User-Agent: http-api/1.45
Content-Type: application/json
Content-Length: 536
Authorization: Basic omissis


senddoc(): entered
{"omissis"}
recvresp(): entered
HTTP/1.1 200 OK
Date: Wed, 14 Sep 2022 17:18:52 GMT
Server: WebServer
Strict-Transport-Security: max-age=3600; includeSubdomains;
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST,GET,OPTIONS,DELETE,PUT
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Content-Type,Authorization
Content-Type: application/json;charset=utf-8
Access-Control-Expose-Headers: ErrorMessage
ErrorMessage:
Content-Length: 0
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-control: no-store, no-cache
X-Frame-Options: deny

SetError() #13: HTTP/1.1 200 OK
recvresp(): end with 200
recvdoc parms: identity 0
header_load_cookies() entered
recvdoc(): entered
SetError() #0:
recvdoc(): Receiving 0 bytes.
recvdoc(): Nothing to receive, exiting...
http_close(): entered
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP Authentication help

Post by Scott Klement »

Good to hear! Thank you for letting us know.
mianlees
Posts: 1
Joined: Thu Mar 09, 2023 3:51 pm

Re: HTTP Authentication help

Post by mianlees »

Hello Scott, hello forum. I am setting up a program to access a webservice.
It is always telling me the message of: DSPLY This page requires a user-id & password.


The code of my program is the following:

D CRLF C CONST(x'0D25')
D rc s 10I 0
D msg s 52A
D MyapiKey c const('"KEY_xxxxxxxxxxxxxxxxxxxxxxx-
D xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-
D xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-
D xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-
D xxxxxxxxxxxxxx"')
D fromAddr s 100A varying
D Subject s 100A varying
D Message s 1000A varying
D myPointer s *
D dataSize s 10I 0
D formData s 32767a varying
D op s 50A
D userid s 50a
D pass s 50a
D Url s 100a
D ResData s a len(16000000) varying
D http_getauthLo s 1000a varying

/free
//http_debug(*on);
http_getauthLo = '/tmp/http_getauthLog.txt';
http_debug(*on : http_getauthLo);

formData = *Blanks;

//
// Montar autentificación
//
userid = '{"API-KEY":';
http_setAuth(HTTP_AUTH_BASIC: userid: MyapiKey);

// Montar tipo de archivo con que trabajar
//
http_setOption( 'content-type'
: 'application/json' );

//
// Montar datos a enviar
//
formData = '{"useid":1, "title:":"foo", "body":"bar"}';

//
// Montar datos a enviar
//
formData = '{"useid":1, "title:":"foo", "body":"bar"}';

formData = %Trim(userid) + MyapiKey + '}';

//
// Montar Url donde acceder
//
Url='http://web.xxxx.net:9600/xxxxxxxxxxxxxxxxx';

rc = http_req( 'POST'
: %Trim(Url)
: '/tmp/prova001.txt' // File to receive
: *omit // String to receive
: *omit // File to send
: formData ); // String to send

//
// Control de errores retornados por el servidor
//
if rc <> 1;
msg = http_error();
dsply msg;
else;
cmd('DSPF ''/tmp/prova001.txt''': 200);
endif;

//
// Fin del pgm
//
*inlr = *on;

Thank you very much for your help.
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: HTTP Authentication help

Post by Scott Klement »

You appear to be putting part of (but not all of) a JSON document into your userid, which doesn't make sense to me. You'll need to read the documenttion for this API to determine how the userid/password is meant to be transmitted. Is it using basic authentication? If so, you don't use a JSON document -- just pass whatever code they use to designate an API key (typically 'apikey', or 'api-key' or just 'key') as the userid, and the key as the password. No JSON characters.

If they expect it to be transmitted as a JSON document, then this is sent in the payload, not with basic authentication.

You'll need to read their documentation -- every API is different.
Post Reply