Retrieving information from the payload of a JWT in a service - kubernetes

The context : kubernet + isio + gateway (HTTPS/JWT) + nodejs service.
Service call :
USER_TOKEN=$(< user.jwt); curl -H "Host: service.server.io" -H "Authorization: Bearer $USER_TOKEN" https://service.server.io:443/feature --cacert service-server.crt --resolve service.server.io:443:10.109.30.39
Everything works well, but I would like to retrieve my user ID stored in the JWT payload { user_uid: xxxxx, group: xxx }.
Ideally, I would like the "user_id" to be injected into the request header so that I can retrieve it from the node.
Header:
"host":"service.server.io"
"user-agent":"curl/7.68.0","accept":"/"
"x-forwarded-for":"172.17.0.1"
"x-forwarded-proto":"https"
"x-request-id":"6783b5c0-6d20-4702-98d7-b04732de90cc"
"x-envoy-attempt-count":"1"
"x-envoy-internal":"true"
"x-forwarded-client-cert":"By=spiffe://cluster.local/ns/server/sa/service;Hash=118639f45b8873d8a38fb947736dbcfb974d12ae54ad46a8ba391ef9130f289e;Subject="";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"
"x-b3-traceid":"8119e0fa2fc19699f301e1c7035e099d"
"x-b3-spanid":"2910ce2ce185e82b"
"x-b3-parentspanid":"f301e1c7035e099d"
"x-b3-sampled":"0"
Thank you for your help,
WCDR

Thanks Istio doc ^_^
outputPayloadToHeader string This field specifies the header name to output a successfully verified JWT payload to the backend. The forwarded data is base64_encoded(jwt_payload_in_JSON). If it is not specified, the payload will not be emitted.
Edit yaml file:
kind: "RequestAuthentication"
Under jws at the same level add: outputPayloadToHeader: x-jwt
Apply changes...
Now a new header input is available "x-jwt" it is a base64 input that contains the payload.

Related

Unable to Send Custom headers for zap-api-scan.py, headers are declared in options.prop

Unable to send Custom headers for zap-api-scan.py, headers are declared in options.prop
I want to use zap to scan a rest API endpoint which requires Authorization & X-api-key header.
To specify the header, I have configured these in options.prop file.
But when I run
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-weekly zap-api-scan.py -t <API URL> -f openapi -z "-configfile /zap/wrk/options.prop"
I feel prop file is not getting picked. I get 401 error, as my Authorization token is not picked up.
Below is how my options.prop file looks
replacer.full_list(0).description=Authorization
replacer.full_list(0).enabled=true replacer.full_list(0).matchtype=REQ_HEADER
replacer.full_list(0).matchstr=Authorization
replacer.full_list(0).regex=false
replacer.full_list(0).replacement=<Token>
replacer.full_list(1).description=x-api-key
replacer.full_list(1).enabled=true
replacer.full_list(1).matchtype=REQ_HEADER
replacer.full_list(1).matchstr=x-api-key
replacer.full_list(1).regex=false
replacer.full_list(1).replacement=<Value>

Keycloak cannot verify user information with a valid token

I'm setting up Keycloak as an authentication server https://github.com/keycloak/keycloak/releases/download/12.0.0/keycloak-12.0.0.zip
Java 11
Documentation: https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/oidc-generic.adoc
I can generate the access_token via /realms/{realm-name}/protocol/openid-connect/token
but I cannot call the userinfo endpoint /realms/{realm-name}/protocol/openid-connect/userinfo using a valid access_token which I get from the first API.
POST http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/token
{
client_secret: ...,
grant_type: ...,
client_id: ...,
}
response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxOE..."
"expires_in": 3600,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "create"
}
But here is the result when I call the get user info API
GET http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/userinfo
Header: Bearer ${access_token}
Are there any suggestions?
Thank you
Post man test
Keycloak server's log is same
Keycloak bug
I think this is an issue on KC 12.0
When I use KC 11.0.3, above APIs work fine
https://github.com/keycloak/keycloak-community/issues/224
The Jira story:
https://issues.redhat.com/browse/KEYCLOAK-17217
Make sure you are calling the endpoint as follows.
First getting the token:
curl -d "client_id=$YOUR_CLIENT_ID" \
-d "client_secret=$YOUR_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/token)
Extract from the JSON response the access_token field (e.g., jq -r .access_token)
Then call the userinfo as follows:
curl -X GET http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/userinfo \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
With Postman:
For a setup with Realm Name = "test", client_id = "test", client_secret = "63b61af0-5a99-41d7-8f9b-4e3059b8b9ab" and using client_credentials grant_type.
Getting the token:
and getting the userinfo:
EDIT
The approach below works with Keycloak 10.0.x, and 11.0.x, but gets exactly the same issues as OP's for the version Keycloak 12.0.x (including the latest release Keycloak 12.0.2).
This seams to be regression added with Keycloak 12.0.0 follow this issue for update information.

Sonos Cloud API HTTP POST always returns 500

I'm trying to control my Sonos One (Gen 1) speaker through cloud APIs but all the POST request return 500 Internal Server Error without error message.
I generated an access_token as described in the documentation and was able to obtain information about the 'households' inside my network, finally both the group id and the player id.
I tried to obtain information about the status of the group by performing a GET on the following endpoint and it worked:
https://api.ws.sonos.com/control/api/v1/groups/{{group_id}}/playback
Same with other GET requestes (e.g. groupVolume).
The problem arise when I try to make a POST (e.g. changing the volume or playing an audioClip), it returns 500 Internal Server Error without any body.
For all the requests I am using Postman including as Headers:
Content-Type: application/json
Authorization: Bearer [token]
Content-Length: ??? (automatically inserted by postman)
while for the body of the change volume request I select the raw option and then select JSON(application/json) option.
The body is:
{
"volume": 80
}
The endpoint is the following: https://api.ws.sonos.com/control/api/v1/groups/{{group_id}}/groupVolume
I also tried controlling the player with node (Package) and it works.
Also tried to use Wireshark to see what requests the node-sonos package is performing but it seems it's not using the Cloud APIs.
I expect the player to change volume, but the API doesn't do anything and doesn't return any error message.
EDIT:
The cURL request from POSTMAN is the following:
curl -X POST \
https://api.ws.sonos.com/control/api/v1/players/<playerID>/audioClip \
-H 'authorization: Bearer XXX' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'postman-token: XXX' \
-d '{
"appId": "edu.myInstitute.myName",
"clipType": "CUSTOM",
"name": "Test",
"streamUrl": "http://...mp3_file_url"
}'

Using http api to init vault does not accept base64 gpg key but CLI does

I am using the http api for initialising vault and encrypting the seal keys and root token, but I am getting
{"errors":["error decoding given PGP key: illegal base64 data at input byte 21"]}
But when I use the CLI it works.
How do I get it working for the http api??
This done using ubuntu 18.04 and gpg (GnuPG) v2.2.4, base64 v8.28, latest vault
Here is the command for command line interface that works, and returns the seal keys and root token encrypted:
./vault operator init -key-shares=2 -key-threshold=2 -address="http://127.0.0.1:8200" -format="json" -root-token-pgp-key="mo.asc" -pgp-keys="mo.asc,mo.asc"
The above was run in the same directory as the vault instance was started using
./vault server -config=vaultconfig.hcl
The vaultconfig.hcl contains
storage "inmem" {}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
mo.asc was obtained using the following:
gpg --gen-key
gpg --export <generated key> | base64 > mo.asc
The command for using the http api that does not work
curl --request PUT --data #payload.json http://127.0.0.1:8200/v1/sys/init
payload.json is
{
"secret_shares": 2,
"secret_threshold": 2,
"pgp_keys": [
"mo.asc",
"mo.asc"
],
"root_token_pgp_key": "mo.asc"
}
This returns:
{"errors":["error decoding given PGP key: illegal base64 data at input byte 21"]}
But if I change the payload.json to
{
"secret_shares": 2,
"secret_threshold": 2
}
it works returning
{
"keys": [
"227e3b43a76b54008249b39285ae1063db0e2bff94bad0f349f4b7fa89195fb7d7",
"2ab2f5ec67191c26735116f5a1cc9b3bab406eff7b57d9632359a0797f2cf5fd3e"
],
"keys_base64": [
"In47Q6drVACCSbOSha4QY9sOK/+UutDzSfS3+okZX7fX",
"KrL17GcZHCZzURb1ocybO6tAbv97V9ljI1mgeX8s9f0+"
],
"root_token": "s.s2GZsomY2tGJfQzHGFjqlYNu"
}
It seems the CLI command accepts that my gpg is base64 encrypted, but the http api does not accept it is encrypted. Although it seems the CLI is using the http api underneath. The http api is working, but only when I add the asc file to the payload.json it does not work.
Am I missing something?
How do I think this so I get encrypted root token and keys when initialising vault via http api?
Thanks

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>'
}