Basic authentication not suppurted by sendHttpGetRequest in ECMAscript 2021?

Platform information:
Hardware: RaspberryPi 4, 8GB
OS: Raspbian GNU/Linux 10 (buster)
Java Runtime Environment: Zulu11.50+19-CA (build 11.0.12+7-LTS)
openHAB version: 3.4.1 - Release Build
JavaScript: ECMAscript 2021

Problem: When trying to use basic authentication via sendHttpGetRequest to an external web server (i.e. external to openHab but on site, same LAN inside my firewall) I can not find any way of making it work. I have tried all possible combinations that I can imagine but the response from openHab is the same:

2023-03-22 22:22:34.928 [ERROR] [enhab.core.model.script.actions.HTTP] - Fatal transport error: java.util.concurrent.ExecutionException: org.eclipse.jetty.client.HttpResponseException: HTTP protocol violation: Authentication challenge without WWW-Authenticate header

I have tried curl both via the Linux CLI and scripts and it returns data as expected. but not sendHttpGetRequest. I do realize that curl is not using Jetty the same was as openHab/Eclipse and I’m starting to suspect the problem is in the implementation.

This code snipplet (one of many attempts) is using the header:

var serverIP = "192.168.xx.xxx";
var serviceRequestPerArray = "/api/v1/production/inverters";
var serviceCreds = "user:password";
var headerHashMap = {
  'Host' : '192.168.xx.xxx',
  'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0',
  'Accept' : 'application/json',
  'Accept-Language' : 'sv-SE,sv;q=0.8,en-US;q=0.5,en;q=0.3',
  'Accept-Encoding' : 'gzip, deflate',
  'DNT' : '1',
  'WWW-Authenticate' : 'Basic',
  'Authorization' : 'Basic aW5zdski6HVyOmJqZTQ1NGM1', //This is username:password Base-64 encoded
};
//      Get data for the total array
rawData = "";
totalURL = "http://" + serverIP + serviceRequestPerArray;
rawData = actions.HTTP.sendHttpGetRequest(totalURL,headerHashMap,5000);
console.info("rawData:" + rawData);

In another incarnation of the code, I use the “traditional” way:

var serverIP = "192.168.xx.xxx";
var serviceRequestPerArray = "/api/v1/production/inverters";
var serviceCreds = "user:password";
var headerHashMap = {
  'Host' : '192.168.xx.xxx',
  'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0',
  'Accept' : 'application/json',
  'Accept-Language' : 'sv-SE,sv;q=0.8,en-US;q=0.5,en;q=0.3',
  'Accept-Encoding' : 'gzip, deflate',
  'DNT' : '1',
};
//      Get data for the total array
rawData = "";
totalURL = "http://user:password@" + serverIP + serviceRequestPerArray;
rawData = actions.HTTP.sendHttpGetRequest(totalURL,headerHashMap,5000);
console.info("rawData:" + rawData);

Both of these versions (and a number of iterations) result in the error above. I have seen basic authentication discussed in a number of threads here on the forum, mostly related to the iOS app but no help there. To play it safe (?) I also enabled Implicit User Role and allowed the Basic Authentication in MainUI → Settings → API Security.

Right now, I’m out of bright ideas and need some help.

Can you do curl -v ?

Very good question. I made three different versions (not bothering to obscure the address and credentials for my solar cells :wink: )
First with curl -v http://192.168.39.210/api/v1/production/inverters
Second with curl -v http://installer:bje454c5@192.168.39.210/api/v1/production/inverters
Third with curl -v --user installer:bje454c5 --basic http://192.168.39.210/api/v1/production/inverters

The result is very interesting. None of them works?! (See log below). If I enter the first URL in a web browser, the request is denied (as expected). However, if I enter the second version the expected data is returned.
Here is the “log”:

openhabian@openHABianPi:~ $ curl -v http://192.168.39.210/api/v1/production/inverters
* Expire in 0 ms for 6 (transfer 0x1e30950)
*   Trying 192.168.39.210...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x1e30950)
* Connected to 192.168.39.210 (192.168.39.210) port 80 (#0)
> GET /api/v1/production/inverters HTTP/1.1
> Host: 192.168.39.210
> User-Agent: curl/7.64.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Date: Wed, 22 Mar 2023 22:45:56 GMT
< WWW-Authenticate: Digest qop="auth", realm="enphaseenergy.com", nonce="1679525156"
< Content-Type: application/json
< Content-Length: 90
< 
{
  "status": 401,
  "error": "",
  "info": "Authentication required",
  "moreInfo": ""
}
* Connection #0 to host 192.168.39.210 left intact

Second version:
openhabian@openHABianPi:~ $ curl -v http://installer:bje454c5@192.168.39.210/api/v1/production/inverters
* Expire in 0 ms for 6 (transfer 0x61e950)
*   Trying 192.168.39.210...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x61e950)
* Connected to 192.168.39.210 (192.168.39.210) port 80 (#0)
* Server auth using Basic with user 'installer'
> GET /api/v1/production/inverters HTTP/1.1
> Host: 192.168.39.210
> Authorization: Basic aW5zdGFsbGVyOmJqZTQ1NGM1
> User-Agent: curl/7.64.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Date: Wed, 22 Mar 2023 22:47:09 GMT
< WWW-Authenticate: ���A
< Content-Type: application/json
< Content-Length: 90
< 
{
  "status": 401,
  "error": "",
  "info": "Authentication required",
  "moreInfo": ""
}
* Connection #0 to host 192.168.39.210 left intact

Third version:
openhabian@openHABianPi:~ $ curl -v --user installer:bje454c5 --basic http://192.168.39.210/api/v1/production/inverters
* Expire in 0 ms for 6 (transfer 0x1c97950)
*   Trying 192.168.39.210...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x1c97950)
* Connected to 192.168.39.210 (192.168.39.210) port 80 (#0)
* Server auth using Basic with user 'installer'
> GET /api/v1/production/inverters HTTP/1.1
> Host: 192.168.39.210
> Authorization: Basic aW5zdGFsbGVyOmJqZTQ1NGM1
> User-Agent: curl/7.64.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Date: Wed, 22 Mar 2023 22:58:49 GMT
< WWW-Authenticate: ���A
< Content-Type: application/json
< Content-Length: 90
< 
{
  "status": 401,
  "error": "",
  "info": "Authentication required",
  "moreInfo": ""
}
* Connection #0 to host 192.168.39.210 left intact
openhabian@openHABianPi:~ $ 

So in the third version, the username:password combination seems to be correctly encoded to Base-64 and the user is identified in the header info. Still, a 401 is returned.

The same URL as in the second version entered in Firefox yields the desired data where the header Authorization is:

Authorization
	Digest username="installer", realm="enphaseenergy.com", nonce="1679258750", uri="/api/v1/production/inverters", response="d6e23e099044f27e7aaab56894706a36", qop=auth, nc=00000011, cnonce="315d406599d891d8"

Is is the realm that is playing tricks on me? (Note that we are no longer using anything in openHab and the end result is identical)

I also tried

curl -v -H 'Authorization: Basic aW5zdGFsbGVyOmJqZTQ1NGM1' http://192.168.39.210/api/v1/production/inverters

401 again…

That looks like Digest authentication, not basic authentication.

1 Like

Looking at the response headers I would certainly agree. In that case, the web browser automagically switches from basic to digest authentication. I’ll rewrite the call tomorrow and give it a try. bbl!

I couldn’t resist leaving the bed to give it a try :slight_smile:

curl -v --digest -u installer:bje454c5 http://192.168.39.210/api/v1/production/inverters

works perfectly!
Tomorrow, I have to figure out how to convince sendHttpGetRequest to handle Digest as well.