CouchDB JWT Authentication with asymmetric keys - jwt

Id like to use JWT Auth with CouchDB as described here
https://docs.couchdb.org/en/3.2.2-docs/api/server/authn.html?highlight=jwt#jwt-authentication
This Stackoverflow question also helped a lot:
Why is the CouchDB JWT Authentication with Auth0 not working for me?
What I have so far is the following configuration:
[chttpd]
authentication_handlers = {chttpd_auth, jwt_authentication_handler}, {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler}
[jwt_auth]
required_claims = exp
[log]
level = debug
[jwt_keys]
rsa:fqT4qxoKNIwJSUSdhEL3KYRjl2tsz-tRMcZr_V16skM = -----BEGIN PUBLIC KEY-----\MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAooP42fI/5PcuI5AflBpn\nLVH9cv4Iz5ubS9J2fFigCSIq6r2nQvgyw/uD+mKO+Gy87zHw+2+2MlYNWiWgBwSJ\naGXE4eZOtqsjiy3q00JMtNfUYCpa8hZWlazIq4beUFjxaDNgTIA1Dm7yk4ZsDKG8\njIzRz51WHAQtnTVGplUYRQD8hVfEiLxB2nbtVMp8rdTTR0hlIv/b262VA1d76BwE\nEzGwgasKlfUxx5usMJ8WRiMMvsgfsrQ/UqH/Oz1BJ/jebbFA2hhQxMZTjk+Sb2hF\nGvxOb7+DNJrgCNyxQfTPThNisOurQf+W6APyP6IMEpkE/E+t4nsPlo9B0+DdjeTW\nwaDcemMzoWmuerjA4PJ7E7CpOOCq6NmjrPJVTjvb61A6zB52LtYLbwqKFVx166Wa\nClhdNspeAXDEP9m1w+TLbvsDBlnVvfJMT/MnBn3nQKGqwjaNJ0VZttn66DAS5Qig\n8iC4R0Ab8Hv22s/WKQA6txXTJ5Fj43TvGbf/kZVteB9hqIdAkoeBKlHQaNz9S4lL\nbt+w1C1CkiO272S/iun+q9il5tbTWVU3mqYEJCgzs2q9RtMTrj81MaM89QRuoJxO\nC/fOcE1mPsFs5PiIOfMcetLNR7jNiwQknK4krmBM9DGrK1tR8hU471ANAOYmqntH\nPUyoxOpC0reaacfiKOqaabkCAwEAAQ==\n-----END PUBLIC KEY-----\n
And I see JWT as a valid option if I query _session
curl 127.0.0.1:5984/_session
{"ok":true,"userCtx":{"name":null,"roles":[]},"info":{"authentication_handlers":["jwt","cookie","default"]}}
But my request with a Bearer Token fails:
curl -H 'Authorization: Bearer $REALLY_LONG_STRING' 127.0.0.1:5984/
{"error":"bad_request","reason":"Not a valid key"}
I think CouchDB cannot parse the PEM string, looks like Im landing here: https://github.com/apache/couchdb/blob/main/src/jwtf/src/jwtf_keystore.erl#L142
That is as much Erlang as I can do, so Im lost now.
Any help?

Can't believe I missed a \n O_o
Works now as advertised
[jwt_keys]
rsa:fqT4qxoKNIwJSUSdhEL3KYRjl2tsz-tRMcZr_V16skM = -----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAooP42fI/5PcuI5AflBpn\nLVH9cv4Iz5ubS9J2fFigCSIq6r2nQvgyw/uD+mKO+Gy87zHw+2+2MlYNWiWgBwSJ\naGXE4eZOtqsjiy3q00JMtNfUYCpa8hZWlazIq4beUFjxaDNgTIA1Dm7yk4ZsDKG8\njIzRz51WHAQtnTVGplUYRQD8hVfEiLxB2nbtVMp8rdTTR0hlIv/b262VA1d76BwE\nEzGwgasKlfUxx5usMJ8WRiMMvsgfsrQ/UqH/Oz1BJ/jebbFA2hhQxMZTjk+Sb2hF\nGvxOb7+DNJrgCNyxQfTPThNisOurQf+W6APyP6IMEpkE/E+t4nsPlo9B0+DdjeTW\nwaDcemMzoWmuerjA4PJ7E7CpOOCq6NmjrPJVTjvb61A6zB52LtYLbwqKFVx166Wa\nClhdNspeAXDEP9m1w+TLbvsDBlnVvfJMT/MnBn3nQKGqwjaNJ0VZttn66DAS5Qig\n8iC4R0Ab8Hv22s/WKQA6txXTJ5Fj43TvGbf/kZVteB9hqIdAkoeBKlHQaNz9S4lL\nbt+w1C1CkiO272S/iun+q9il5tbTWVU3mqYEJCgzs2q9RtMTrj81MaM89QRuoJxO\nC/fOcE1mPsFs5PiIOfMcetLNR7jNiwQknK4krmBM9DGrK1tR8hU471ANAOYmqntH\nPUyoxOpC0reaacfiKOqaabkCAwEAAQ==\n-----END PUBLIC KEY-----\n
``

Related

Keycloak does not have all the Keys available in the storage

I have created a realm and added new keystore(RS384) in the Providers section
When I tried authenticate using postman. I am getting below error in Keycloak console
PublicKey wasn't found in the storage. Requested kid: 'Y3RDLAudovJPEU3Z9BMJL3OyuzqsgAj4424CpxnJqkI' . Available kids: '[]'
Kid is available in the Keys section for the Realm. I am not sure what is causing that. Any help on this is so much appreciated
Edit
Client Authentication
Added JWKS keys from certs endpoint
In Postman made call to token endpoint with client_assertion which has signed JWT and got response back "Invalid client: Unable to load Public key "
I think you gave wrong a value(or format) of "Private RSA Key" and "X509 Certificate" file when you add the key-store at Keycloak UI.
it is possible to get the public Key for RS384 by Postman and UI.
I demoed with Keycloak 18.0.0 with "ssh-keygen" & "openssl" on Ubuntu.
Generate RS384 private key and public key and certification file
ssh-keygen -t rsa -b 4096 -E SHA384 -m PEM -P "" -f RS384.key
openssl req -new -x509 -key RS384.key -out RS384-cert.pem -days 360
it will create three files
RS384-cert.pem <- certification file
RS384.key <- private key
RS384.key.pub <- public key
Add Keystore with 1.'s files
New Keystore will be created
Can get Key by Postman
can compare public key between UI and openssl generated it.
you can check API call value and JWT creator web site
with KID and public key
https://russelldavies.github.io/jwk-creator/
The issue is I did not add "use":"sig" in the JWKS that is kid is not available

Why is the CouchDB JWT Authentication with Auth0 not working for me?

I have been trying to use the JWT authentication method in CouchDB together with Auth0. Following the Documentation at https://docs.couchdb.org/en/stable/api/server/authn.html#jwt-authentication , i added the authentication_handlers in my default.ini file and configured jwt_auth and jwt_keys like this:
[jwt_auth]
; List of claims to validate
required_claims = alg,kid,sub
[jwt_keys]
rsa:<kid> = -----BEGIN PUBLIC KEY-----\n
<PublicKey>
\n-----END PUBLIC KEY-----\n
I got the kid and the public key from Auth0 (https://[myDomain]/.well-known/jwks.json). Now when i request the JWT Token and add it to the CouchDB request against the _session endpoint i get the following response:
{
"ok": true,
"userCtx": {
"name": null,
"roles": []
},
"info": {
"authentication_handlers": [
"cookie",
"default"
]
}
}
I feel like i am doing something wrong within the default.ini file. Can anyone help me?
It looks like you haven't enabled JWT authentication in CouchDB. I say this because this:
"info": {
"authentication_handlers": [
"cookie",
"default"
]
}
should also include "jwt".
To get that, the [chttpd] block in CouchDB config should include:
{chttpd_auth, jwt_authentication_handler}
In addition, I don't think you need to have those three required claims listed. I got this working just the other day, and as those are required by Couch, you don't need to list them. Indeed, when I listed any one of them I got an error about "duplicate requirement" or something.
Also, make sure there's no iss (issuer) claim in the JWT. This is an issue likely to be fixed in a future release, but as of the time of writing, to get this to work with Couch 3.1 I had to explicitly make sure there was no iss claim.
More details in this issue.
So this is pretty embarrassing but my problem was that I didn't enter the public key in PEM format, so all i had to do was to use this command:
curl https://[myDomain]/pem -s | openssl x509 -pubkey -noout
to get the PEM format and use it to configure the CouchDB.

What is the correct way to test an API with token api_key:access_token header?

Following the below steps:
created a new app at https://developers.kite.trade/apps
obtained the <API key> from the app details page
obtained the <API secret> from the app details page
calling an API called holdings API using curl like this:
curl -X GET https://api.kite.trade/portfolio/holdings -H 'Authorization: token <API key>:<API secret>' -H 'X-Kite-Version: 3'
All the steps look correct to me however I'm getting the following error:
{
"status": "error",
"message": "Incorrect `api_key` or `access_token`.",
"data": null,
"error_type": "TokenException"
}
I regenerated the <API secret> 3 times from the app details console.
Now, the question here is not about why I'm getting the error from https://api.kite.trade
The question is whether the authorization header is correct or not?
I have seen many APIs asking for base64 encoded headers so I did that too but the API seems not working.
Is it not the right approach for testing an API?
Try using Postman to test your API request. Also, check what kind of authentication your API is using ( oAuth 2.0, etc). If that's the case, your request headers might look something like this:
{
Authorization: 'Bearer <API token>'
}

Playground authorization endpoint results in error: "insecure_transport"

First of all, great work. I donated because this could really save me lots of headaches. New to oauth2 and authentication in general. I signed up and registered # https://play.authlib.org/, added newapp. When I tried to authorize with the following uri:
https://play.authlib.org/oauth2/authorize?response_type=code&client_id=FhHzedZ9kdtQeTQRCwTgZELPdnHCEfEo7K0771U9XircD9Hh&state=e3dC66BGid2z0IwBinMgLKJ92IiD1r
it failed with:
{
"error": "insecure_transport",
"error_description": "OAuth 2 MUST utilize https."
}
Am I miss something?
There is nothing wrong with your code. The server itself has a bug (just fixed).
The playground is powered by Authlib v0.5 now.
You need to learn how to send requests for client_credentials:
https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials

JENKINS Authentication Fails

I am getting the following error while trying to trigger Jenkins job from any REST Client
Authentication required
<!-- You are authenticated as: anonymous
Groups that you are in:
Permission you need to have (but didn't):
hudson.model.Hudson.Read
... which is implied by: hudson.security.Permission.GenericRead
... which is implied by: hudson.model.Hudson.Administer
-->
</body> </html>
The request is getting triggered while using curl from terminal
I am using the following syntax
http://user:apiToken#jenkins.yourcompany.com/job/your_job/build?token=TOKEN
[ref :https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients]
ie. curl -X POST http://user:apiToken#jenkins.yourcompany.com/job/your_job/build?token=TOKEN
Check this "This build is parameterized " , select the credentials parameter from drop down.
Use this
curl -X POST http://jenkins.rtcamp.com/job/Snapbox/buildWithParameters --user "username:password"
It solved my authentication problem.
I hope it will help others too.
My development team's configuration settings were matrix-based security so I had to find my group and give my group workspace access.
1.Click on Manage Jenkins .
2.Click on Configure Global Security .
3.in matrix-based security change:
Overall - Read
Job - Build
Job - Read
Job - Workspace
Then
POST jobUrl/buildWithParameters HTTP/1.1
Host: user:token
Authorization: Basic dWdlbmxpazo4elhjdmJuTQ==
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
Branch=develop
For me
https://user:password#jenkins.mycompany.org/job/job_name/build?token=my_token
in https://jenkins.mycompany.org/configureSecurity
disable CORS
hope this help
Try using the -u parameter to specify the credentials:
curl -u user:apiToken -X POST http://jenkins.yourcompany.com/job/your_job/build?token=TOKEN
I provided header Authorization parameter with value :
BASIC base_64encoded(username:password) and it worked fine.
Authorization Basic bmltbWljdjpqZX*********
Simply disable "CSRF Protection" in the global Security Options, because those URLs don't send post data identification.
focal point :
username:password#
curl -u user:apiToken -X POST http://username:password#jenkins.yourcompany.com/job/your_job/build?key1=value1&key2=value2 ...
If you are encountering this problem with jenkins api client in ruby.
I figured Jenkins is blocking all the get request, instead use api_post_request.
Also, you have to generate api token because normal password is not working anymore.
#client = JenkinsApi::Client.new(
server_url: "",
username: '',
password: ""
)
SITE_FILE_PATH = 'artifact/target/site'.freeze
#jenkins_uri=''
#jenkins_job_name=''
def latest_test_file_path
"/job/#{#jenkins_job_name}/job/master/lastSuccessfulBuild/#{SITE_FILE_PATH}/Test-Results/test-results.html"
end
puts #client.api_post_request(latest_test_file_path,{},true).body
you can set the parameter true if you want the raw response.
default parameter or passing false will just return response code.
Also make sure to construct the right prefix.
You can refer to the above snipped.