ruflin / Elastica

Elastica is a PHP client for elasticsearch
http://elastica.io/
MIT License
2.26k stars 737 forks source link

CURLAUTH_ANY doesn't work with ElasticSearch Xpack Authentication #1638

Open malcomhamelin opened 5 years ago

malcomhamelin commented 5 years ago

https://github.com/ruflin/Elastica/blob/f070d3bc9f9836648efd120a6164f85c6831da4b/lib/Elastica/Transport/Http.php#L108

I tracked an error while trying to setup Elastica and FOSElastica with my ElasticSearch 6.8.0 which is protected by Xpack Authentication.

It doesn't work with CURLAUTH_ANY but does with CURLAUTH_BASIC

p365labs commented 5 years ago

hi @malcomhamelin can u report the error u got?

malcomhamelin commented 5 years ago

I opened earlier a stackoverflow subject here earlier today.

It wasn't taking into account at all my username and my password (wether it was setup in the config file under fos_elastica or written directly into Http.php of Elastica), when I was trying to do in my console:

php bin/console fos:elastica:populate

It was saying :

In Http.php line 182:

  action [indices:admin/create] is unauthorized for user [anonymous_user]

But now I changed ANY to BASIC, it works just fine (and I don't understand why).

ruflin commented 5 years ago

Found this in the PHP docs:

CURLAUTH_ANY is an alias for CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM.

But not sure i can make sense of it on why ANY does not work. Ideas?

Turgon37 commented 5 years ago

Hello I've encountered the same issue with searchguard (another security plugin) In fact the problem is related to plugin behaviour. In normal web, a restricted resource ask for credential using the 'www-authenticate: Basic realm="Restricted"' header. So, the browser understand it and prompt the user for name+password and send the request again with theses informations.

In my searchguard configuration, I have two authorization backends, the first is internal and the second is a ldap server. In order to allow the two backend to be used, I've disabled the challenge on first backend ( https://docs.search-guard.com/latest/http-basic-authorization ). So if the authorization fail on internal backend the ldap backend is test then.

In php curl doc ( https://www.php.net/manual/en/function.curl-setopt.php) , I notice the following sentence

""" The bitwise | (or) operator can be used to combine more than one method. If this is done, cURL will poll the server to see what methods it supports and pick the best one. """

So I suppose that if the curl lib do not receive a 401 status code with the correct www-authenticate header, it will not try to send the authorization header with username + password. And finally it talk to ES without any credentials.

In my case, I have not configured the ldap backend yet, so the problem whould not have appeared if I did it.

I think the simple fix is to allow the user to set manually the CURL option and use "any" option if the user do not provide any config value. The documentation should also be updated to inform about this behaviour