Amit Yadav
Amit Yadav

Reputation: 5014

Generate JWT Token in Keycloak and get public key to verify the JWT token on a third party platform

There is an Endpoint to a backend server which gives a JSON response on pinging and is protected by an Apigee Edge Proxy. Currently, this endpoint has no security and we want to implement Bearer only token authentication for all the clients making the request. All the clients making the requests to API will send that JWT token in Authorization Bearer and Apigee Edge will be used to verify the JWT Token.

How do I use Keycloak to generate this JWT token?

Also, Apigee needs a public key of the origin of the JWT token (the server which signed the JWT token, in this case, I believe that is Keycloak). So my second doubt is, while I use Keycloak to generate the JWT token, how to get the public key using which the server will verify if the token is valid?

Upvotes: 54

Views: 118947

Answers (2)

Dzmitry Dranitski
Dzmitry Dranitski

Reputation: 669

Update for keycloak 23

You can install it with this docker-compose.yml using docker compose up:

networks:
  keycloak-network:
    external: true

services:
  postgres:
    container_name: backend-postgres
    image: postgres:15.6-alpine
    volumes:
      - ./postgres:/var/lib/postgresql/data
      - ./00_create_db.sql:/docker-entrypoint-initdb.d/create-db.sql
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - 5432:5432
    networks:
      - default
    healthcheck:
      test: [ "CMD", "pg_isready", "-q", "-d", "postgres", "-U", "postgres" ]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 60s
    restart: unless-stopped

  keycloak:
    container_name: backend-keycloak
    image: bitnami/keycloak:23.0.6
    environment:
      KEYCLOAK_DATABASE_VENDOR: postgresql
      KEYCLOAK_DATABASE_HOST: postgres
      KEYCLOAK_DATABASE_PORT: 5432
      KEYCLOAK_DATABASE_NAME: keycloak
      KEYCLOAK_DATABASE_USER: postgres
      KEYCLOAK_DATABASE_PASSWORD: postgres
      KEYCLOAK_DATABASE_SCHEMA: public
      KEYCLOAK_ADMIN_USER: keycloak
      KEYCLOAK_ADMIN_PASSWORD: keycloak
      KC_HTTP_ENABLED: 'true'
    links:
      - postgres
    ports:
      - 8080:8080
    networks:
      - default
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy

00_create_db.sql:

CREATE DATABASE keycloak;

Then you open http://localhost:8080/admin and log in with keycloak:keycloak.

Create a realm realm create button

Create a client under realm client create button

Select OpenID Connect as Client type. client setup

Now you can get:

  • all security endpoints: GET http://localhost:8080/realms/<REALM>/.well-known/openid-configuration
  • certs: GET http://localhost:8080/realms/<REALM>/protocol/openid-connect/certs
  • public key http://localhost:8080/realms/<REALM> (some libs need it to validate JWT, for example js jsonwebtoken one)
  • token (with Client authentication off in client settings): curl -X POST 'http://localhost:8080/realms/<REALM>/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' -d 'client_id=<CLIENT_ID>' -d 'username=<USER>' -d 'password=<PASS>' -d 'grant_type=password' -d 'scope=email profile
  • token (with Client authentication on in client settings): curl -X POST 'http://localhost:8080/realms/<REALM>/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' -d 'client_id=<CLIENT_ID>' -d 'username=<USER>' -d 'password=<PASS>' -d 'grant_type=password' -d 'scope=email profile -d 'client_secret=<CLIENT_SECRET>'

Upvotes: 5

Amit Yadav
Amit Yadav

Reputation: 5014

This got figured out with the help of this medium article. All the steps I have mentioned below have a detailed description in the article (Refer step 1 to 9 for token part, other steps are related to Spring Boot application) but I would like to give a overview of those in reference to my question.

Generating a JWT token using KeyCloak

  1. Install and run KeyCloak server and go to the endpoint (e.g http://localhost:8080/auth). Log in with an initial admin login and password (username=admin, password=admin).
  2. Create a Realm and a Client with openid-connect as the Client Protocol.
  3. Create users, roles and map Client Role To User.
  4. Assuming the server being on localhost, visiting the http://localhost:8080/auth/realms/dev/.well-known/openid-configuration gives details about all security endpoints
  5. http://localhost:8080/auth/realms/dev/protocol/openid-connect/token sending a POST request with valid details to this URL gives the JWTtoken with.

Getting the public key of the KeyCloak server

  • Going to Realm Settings and click on Public key pops up with the Public key of the server for that Realm. Refer to this image for better understanding.
  • Add -----BEGIN PUBLIC KEY----- and append -----END PUBLIC KEY----- to this copied public key to use it anywhere to verify the JWTtoken. You public key should finally look something like this:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhAj9OCZd0XjzOIad2VbUPSMoVK1X8hdD2Ad+jUXCzhZJf0RaN6B+79AW5jSgceAgyAtLXiBayLlaqSjZM6oyti9gc2M2BXzoDKLye+Tgpftd72Zreb4HpwKGpVrJ3H3Ip5DNLSD4a1ovAJ6Sahjb8z34T8c1OCnf5j70Y7i9t3y/j076XIUU4vWpAhI9LRAOkSLqDUE5L/ZdPmwTgK91Dy1fxUQ4d02Ly4MTwV2+4OaEHhIfDSvakLBeg4jLGOSxLY0y38DocYzMXe0exJXkLxqHKMznpgGrbps0TPfSK0c3q2PxQLczCD3n63HxbN8U9FPyGeMrz59PPpkwIDAQAB
-----END PUBLIC KEY-----

Validating the token on a third party platform

  • jwt.io is a great website for validating JWTtokens. All we have to do is paste the token and public key. Read the introduction of the website here to know more about validating the tokens.

Upvotes: 109

Related Questions