Reputation: 5014
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
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
.
Select OpenID Connect as Client type
.
Now you can get:
http://localhost:8080/realms/<REALM>/.well-known/openid-configuration
http://localhost:8080/realms/<REALM>/protocol/openid-connect/certs
http://localhost:8080/realms/<REALM>
(some libs need it to validate JWT, for example js jsonwebtoken
one)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
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
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.
openid-connect
as the Client Protocol
.localhost
, visiting the http://localhost:8080/auth/realms/dev/.well-known/openid-configuration gives details about all security endpointsRealm 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. -----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-----
Upvotes: 109