Basic-Auth plugin / consumers does not work similar, comparing DB-Less and Kong with Postgres
kong.yaml For databaseless
---
_format_version: '1.1'
services:
- name: httpbin
url: http://httpbin.org/anything
routes:
- name: httpbin
service: httpbin
paths:
- "/httpbin"
plugins:
- name: basic-auth
consumers:
- username: Leandro
basicauth_credentials:
- username: carneiro
password: abc123
Commands for kong with database:
http POST ${KONG}:8001/consumers username=Leandro
http POST ${KONG}:8001/consumers/Leandro/basic-auth username=carneiro password=abc123
http POST http://${KONG}:8001/services/ \
name="httpbin" \
url="http://httpbin.org/anything"
http POST http://${KONG}:8001/services/httpbin/routes \
paths:='["/httpbin"]' \
name=httpbin
http POST http://${KONG}:8001/routes/httpbin/plugins \
name=basic-auth
curl -iu carneiro:abc123 ${KONG}:8000/httpbin
Kong DBLess output:
HTTP/1.1 401 Unauthorized
Date: Thu, 25 Apr 2019 17:53:41 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 48
{"message":"Invalid authentication credentials"}
Kong with database can authenticate.
Comparing the consumer endpoint (http GET localhost:8001/consumers/Leandro/basic-auth):
password in Databaseless have not been hashed
Hi @carnei-ro, I have been able to reproduce, and the problem is indeed as you describe. The basicauth_credentials DAO is performing the hashing in database mode to keep the password hashed at rest, but the declarative config parser is not doing that. It's something we need to fix on our end, thank you for reporting.
In the mean time, what does work is keeping the password hashed in the YAML file. This script produces a hash:
hash_basicauth.lua
#!/usr/bin/env resty
if not arg[1] then
print("usage: hash_basicauth.lua <password> [<uuid>]")
print("example: hash_basicauth.lua abc123")
os.exit(1)
end
local crypto = require "kong.plugins.basic-auth.crypto"
local utils = require "kong.tools.utils"
local id = arg[2] or utils.uuid()
print("consumer uuid: " .. id)
print("password hash: " .. crypto.hash(id, arg[1]))
Using the generated id and hash in your example: (note that the consumer.id needs to be provided to match the hash)
_format_version: '1.1'
services:
- name: httpbin
url: http://httpbin.org/anything
routes:
- name: httpbin
service: httpbin
paths:
- "/httpbin"
plugins:
- name: basic-auth
consumers:
- username: Leandro
id: cbb297c0-14a9-46bc-ad91-1d0ef9b42df9
basicauth_credentials:
- username: carneiro
password: 23d696aebd2ccacb9e5efb790baa1c72260f2ba7
the request goes through:
$ curl -iu carneiro:abc123 localhost:8000/httpbin
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 529
Connection: keep-alive
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Date: Thu, 25 Apr 2019 20:36:15 GMT
Referrer-Policy: no-referrer-when-downgrade
Server: nginx
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Kong-Upstream-Latency: 252
X-Kong-Proxy-Latency: 1
Via: kong/1.1.2
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Authorization": "Basic Y2FybmVpcm86YWJjMTIz",
"Host": "httpbin.org",
"User-Agent": "curl/7.63.0",
"X-Consumer-Id": "cbb297c0-14a9-46bc-ad91-1d0ef9b42df9",
"X-Consumer-Username": "Leandro",
"X-Credential-Username": "carneiro",
"X-Forwarded-Host": "localhost"
},
"json": null,
"method": "GET",
"origin": "127.0.0.1, 189.27.145.250, 127.0.0.1",
"url": "https://localhost/anything"
}
I updated the title and initial report comment just to clarify that this affects basic auth only, due to how basic auth modifies entity values
Is there any improvement or workaround?
It is being worked on, but we are coming up with a more general solution
for this beyond basic-auth. It won't make it in time for Kong 1.2 but we
intend to have it in Kong 1.3.
>
Thanks for the clarification and your work @hishamhm .
Hi, what is the expected release date for 1.3? Or if this is available in a minor version anytime soon? we have this same issue. The workaround works but it's a bit hacky.
Hi, 1.3.0rc1 was released yesterday and there were some changes since this issue was created.
Currently (as in 1.3.0rc1, or the next branch) the passwords are encrypted when they are imported (see my comment in #4830 for an example). So I think the main problem highlighted on this issue has been addressed: Importing credentials will now work (and only work) if the passwords on the yaml file are unencrypted.
We are discussing internally whether we should extend this functionality further, to also allow importing encrypted passwords. Nothing has been decided yet on that regard.
@kikito I think you mixed up db_import with DB-less. It remains a problem in DB-less: the issue should remain open.
Yes, my apologies.
This should now be fixed, and will be in 1.4.0rc1. One note though, we don't support hashed passwords in declarative at this point (so it is kinda reverse to previous in that sense). We look forward to support both in future. I'll close this now. Please reopen if it still shows up!
Can someone help me I'm using database less api authentication and authorisation in Kong
I have done changes in ingress.yaml
When I hit the url by uing below command
Curl -i -H 'api-key' url it is showing success but removing api key shoowng key not found error
Most helpful comment
Hi @carnei-ro, I have been able to reproduce, and the problem is indeed as you describe. The
basicauth_credentialsDAO is performing the hashing in database mode to keep the password hashed at rest, but the declarative config parser is not doing that. It's something we need to fix on our end, thank you for reporting.In the mean time, what does work is keeping the password hashed in the YAML file. This script produces a hash:
hash_basicauth.lua
Using the generated id and hash in your example: (note that the consumer.id needs to be provided to match the hash)
the request goes through: