THttpServer with CORS and Htdigest Auth

Hi,

  • new THttpServer("http:8080?auth_file=.htdigest&auth_domain=test"); works: it successfully asks for auth.

  • new THttpServer("http:8080;cors;noglobal"); works too: Access-Control-Allow-Origin is given and I can fetch data in browser from another domain than origin

But together, it doesn’t work. I’ve tried various combinations:

new THttpServer("http:8080?auth_file=.htdigest&auth_domain=test;cors;ro;noglobal"); 
// auth OK but no Access-Control-Allow-Origin
new THttpServer("http:8080?cors=1&auth_file=.htdigest&auth_domain=test;ro;noglobal"); 
// auth OK but no Access-Control-Allow-Origin
new THttpServer("http:8080;cors;ro;noglobal?auth_file=.htdigest&auth_domain=test");   
// Access-Control-Allow-Origin OK but no auth

I am in a case where having both at the same time would be useful (even if ok, doing an auth request from a browser, i.e. client code containing auth code might seem not-so-useful, but here it would help a lot for internal testing purposes during a few months).

Do you have any idea? Maybe @linev?

Thank you again

Hi @jb023, I think @linev is off until Monday, but he can probably answer you after he’s back.
Otherwise maybe @Danilo knows about it?

Thank you @silverweed for your feedback!

Hi,

This is not mentioned in documentation - while it is very special use-case.
But one can see possible solution in the httpaccess.C tutorial in comments:

   // start http server and allows CORS access to local files
   // first copy hsimple.root file to current directory
   // THttpServer* serv = new THttpServer("http:8080?auth_file=auth.txt&auth_domain=root&cred_cors&cors=https://root.cern");
   // And finally file can be opened via url: https://root.cern/js/dev/?with_credentials&file=http://localhost:8080/currentdir/hsimple.root

If authentication enabled, on the server side one have to configure exact CORS domain from which requests will come and enable Access-Control-Allow-Credentials header with cred_cors option.
On the client side one should specify that requests should be submitted with the credentials - therefore for JSROOT url option with_credentials should be used.

After all - not very simple.
And be aware - digest authentication is weak.

Regards,
Sergey

Thank you for your answer @linev.

Would you have a simple example with CURL showing that Access-Control-Allow-Origin is present?

I tried:

new THttpServer("http:8080?auth_file=.htdigest&auth_domain=test&cred_cors&cors=https://localhost");

then run the THttpServer, and then do:

curl -i -H "Origin: http://localhost" http://localhost:8080/
# "Origin" header is important to trigger a CORS request like in a browser

I successfully have a HTTP 401 response (this is normal because of authentication not done yet), but I don’t see the Access-Control-Allow-Origin header:

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache, no-store, must-revalidate, private, max-age=0
Expires: 0
Pragma: no-cache
Content-Length: 0
WWW-Authenticate: Digest qop="auth", realm="test", nonce="1750666932334316469"
Date: Mon, 23 Jun 2025 08:39:38 GMT
Connection: close

What do you think I should change to actually get the Access-Control-Allow-Origin?

Have a good day.

Hi,

In case of curl CORS is not used and can be ignored. Just do:

curl --user "admin:admin"  http://localhost:8080/hpx/root.json --digest -o file.json  

This is object from httpaccess.C example.

Regards,
Sergey

Yes I know that from curl CORS is not used, I just wanted to “simulate” easily what happens in a browser (where CORS is relevant).

In my real use case, I need, from Javascript code to fetch("http://localhost:8080/h.json").then(r => r.json()).then(data => { console.log(data); }); (with another domain than localhost, and also other objects than /h.json).

How to do that without being blocked by CORS?

PS: I already know how to deal with htdigest auth from JS: first do a normal request, get a 401, get the WWW-Authenticate nonce, etc. and then do a second request, etc. I will be able to handle this. But only the CORS is blocking me.

Thanks again @linev.

Hi,

Which library you are using for fetch()?
It must specify that XMLHttpRequest issued with credentials. Like in JSROOT:

xhr.withCredentials = true;

But only the CORS is blocking me

It is complicated and sometime different browsers handle them differently.
But I described how server and JSROOT client can be configured.
You can try to debug from some browser session which headers are exchanged to see them and compare with you library.

Regards,
Sergey

Thank you for your answer @linev.

I’m using the standard JS fetch API (Using the Fetch API - Web APIs | MDN): (Fetch is the modern replacement for XMLHttpRequest: unlike XMLHttpRequest, which uses callbacks, Fetch is promise-based and is integrated with features of the modern web such as service workers and Cross-Origin Resource Sharing (CORS).)

Would you have a small example of client JS code (using JSROOT or direct fetch or XMLHttpRequest) showing how to get and console.log http://localhost:8080/h.json without being blocked by CORS?

Here example of such macro:

http_cors.C (1.7 KB)

It configures CORS for https://root.cern domain.
And you should be able to open URL:

https://root.cern/js/latest/?with_credentials&json=http://localhost:8080/hpx/root.json

I never tried fetch API, but see in docu some browser compatibility problems about Authorization.