Introduction to Keycloak, from installation to auth flows

In the next few posts, I will explore using OIDC (mainly Keycloak) with Kong Gateway(Enterprise). The topics I will be covering include:

  1. Using different authorization flows to protect API services.
  2. Mapping virtual credentials to work with other plugins.
  3. Directory mapping for Kong manager.
  4. Application registration with OIDC.

As these are a lot of content, I will write a new post for each topic and reference each other. My goal is to give you an overal view of what you can achieve using OIDC with Kong and most importantly show you how to make it work step by step.

In today’s post, I will only cover the basics of keycloak. We will be using keycloak to work with Kong.

Install keycloak with docker

Installing Keycloak is pretty easy, users can use a database to store all information. As it is for demonstration purposes, you can use below docker-compose.yaml to start a keycloak container behind Traefik quickly.

Traefik will be responsible for proxying requests to keycloak and handle TLS certificate automatically. If you are not sure how to use Traefik, please check my previous posts/videos.

Please note this set up is for testing purpose only and it does not have data persistence. You might want to add a database if you plan to use it in long term. (Even in dev environment)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
version: '2.1'
services:
keycloak:
networks:
- proxy
container_name: keycloak
image: jboss/keycloak
environment:
# Create initial username and password
KEYCLOAK_USER: <USER_NAME>
KEYCLOAK_PASSWORD: <PASSWORD>
PROXY_ADDRESS_FORWARDING: "true"
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.keycloak-secure.entrypoints=websecure"
- "traefik.http.routers.keycloak-secure.rule=Host(`key.yourdomain`)"

networks:
proxy:
external: true

Prepare data in keycloak

After we’ve installed keycloak, let’s put in some data to use in our demo.

Create a new realm

You use a realm to hold all your applications and users data. Different realms Do NOT share data with each other. For more information about additional realm settings, please check official documentation here.

Create Users and Groups

This is pretty self-explainatory. I will create a couple users and groups for the demo.

Create a client

  1. Let’s use demo-client-id as client_id. This will be used in all your requests and in the Keycloak database to identify the client. Other IDPs normally generates client id as random string for user.

  2. On client page, we need to change Access Type to confidential and switch Service Accounts Enabled to on. This is for testing client credentials flow.

  3. Go to Credentials tab and save Secret. We will need it as client_secret in our calls.

Now we are ready to do some test.

Authentication flows

I will cover 4 authentication flows in my examples as I will use them in my future posts.

Password

Password flow is used to authenticate users. The openid scope returns an id_token which includes users information which we can use for consumer mapping and group mapping in future posts.

1
2
3
4
5
6
7
8
9
curl --request POST \
--url https://<KEYCLOAK_HOST>/auth/realms/<KEYCLOAK_REALM>/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=password \
--data client_id=demo-client-id \
--data client_secret=<CLIENT_SECRET> \
--data username=admin \
--data password=admin \
--data scope=openid

Client credentials

Client credential flow is machine to machine flow. The access_token returned is not bond to a specific user but a service account. We can use it in our applicaiton registraion of developer portal in future.

1
2
3
4
5
6
curl --request POST \
--url https://<KEYCLOAK_HOST>/auth/realms/<KEYCLOAK_REALM>/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=demo-client-id \
--data client_secret=<CLIENT_SECRET>

Introspection

Some companies requires the token to be generated locally and pass the access_token to the requests. Keycloak has introspection endpoint which we can use to verify token validity as well as getting the content of token.

1
2
3
4
5
6
curl --request POST \
--url https://<KEYCLOAK_HOST>/auth/realms/<KEYCLOAK_REALM>/protocol/openid-connect/token/introspect \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data client_id=demo-client-id \
--data client_secret=<CLIENT_SECRET>
--data token=<TOKEN>

Authorization code

This flow is best to be demonstrated with a log in page. I will use an external tool oauth.tools to demo this flow.

  1. Click Environments on the top right corner.
  2. Enter your metadata url and click refresh. metadat url is in the form of https://<KEYCLOAK_HOST>/auth/realms/<KEYCLOAK_REALM>/.well-known/openid-configuration .
  3. Go to Client tab and put in your client_id and secret. Make sure Code Flow is ticked.
  4. Go back to Keycloak admin console and make sure https://oauth.tools/callback/code is added in Valid Redirect URIs list.
  5. Go back to oauth.tools, click Demo: Code Flow from left sidebar.
  6. Select demo-client-id in settings and remove read scope.
  7. Unticked Open in iFrame and click Run.

We should see our tokens on the right sidebar.

That’s all for today, I am planning to make a video to show these exact steps asap as long article might still be confusing sometimes.

Stay tuned.