4

Postgrest APIs can be secured through inbuilt JWT tokens or through a third party service like Auth0, Okta or Keycloak (http://postgrest.org/en/v5.0/install.html)

We want to consume JWT provided by a Keycloak only , but there is very limited document available.

Can anybody guide me how can I secure postgrest apis through keycloak ?

thanks

user2590014
  • 71
  • 1
  • 5

1 Answers1

2

UPDATE: Simple method with curl examples

  1. Install keycloak, add realm and client
  2. get the keys
curl https://$KEYCLOAK_URL/auth/realms/$REALM/protocol/openid-connect/certs

copy the first element of the keys array and use it in the postgrest configuration for the jwt-secret variable

  1. use .preferred_username as the value of role-claim-key in postgrest configuration

Assuming you 've done the above you can test your installation:

  1. Get token
curl -X POST https://$KEYCLOAK_URL/auth/realms/$REALM/protocol/openid-connect/token \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d "username=$USERNAME" \
 -d "password=$PASSWORD" \
 -d 'grant_type=password' \
 -d "client_id=$CLIENT"
  1. Use the access_token element of the reply for your requests to postgrest
curl -H "Authorization: Bearer $ACCESS_TOKEN" $POSTGREST_URL/your_table

There are several ways to do it, I'll just describe one:

  1. Set up keycloak to pass the claims you want in the token. ( Probably you would want a claim of type "role": "username" )
  2. Get the key keycloak is using and pass it in the jwt-secret section of the postgrest configuration
  3. Set up a web server to communicate with keycloak and get the tokens.
  4. Pass the token to the browser
  5. Use the token to access postgrest

Details

  1. In keycloak admin console go to: /#/realms/<realm name>/clients/<client id>/mappers and set the claims you want
  2. In keycloak admin console at #/realms/<realm name>/keys you can get your rsa public key, translate it to jwk format and save it to the postgrest configuration. In order to translate it to jwk
  • Translate it to pem format by enclosing it in -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY-----
  • Translate it to jwk format. A nice tool pem-jwk
  1. There are infinite options. A node js example: https://github.com/keycloak/keycloak-nodejs-connect/tree/master/example that uses the keycloak-connect package

  2. You can read the token at req.kauth.grant and place it at a hidden field of the html you send to the browser

  3. From the browser read the token and place it at the authentication header with the bearer prefix. If you use axios:

     axios({
       method: 'get',
       url: 'your url',
       headers: { 'authorization': `Bearer ${token}` }
     })
    
  • Is this possible to achieve without a separate web server? Ie. using only Keycloak and PostgREST? I was hoping PostgREST could replace my backend web server. But maybe this isn't possible when authentication is added? – runeks Feb 16 '21 at 08:01
  • Having set up keycloak with postgrest (first 2 steps) you can use any client you wish ( even curl ) to consume the api. One simple workflow is: 1) Call keycloak with username/password and get a token. 2) Call postgrest using the token. There is also a browser-only js client https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter but again you'll need a web server to serve the relevant static pages – Alexis Panagiotopoulos Feb 17 '21 at 09:58