My little Keycloak Book © 2024 by Dirk Strauss is licensed under CC BY-NC-SA 4.0. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/

Warning
Disclaimer: this is a work in progress and may contain errors. If you find any, please report them to this project’s issue tracker. A preview version can be found here.

Introduction

Hi, all.

This small book here is a summary of knowledge I gathered during my time spending with Keycloak.

Keycloak is a server software written in Java, running in Quarkus, to allow authentication and authorization against other identity providers, like Github, Google, Facebook etc., or use another backing database, such as Postgresql or LDAP.

It can be used for your own application to perform authentication and authorization so that you can secure your application.

Keycloak can act as a wrapper to so called identity providers. For example, if you want to use Google as an identity provider, you can do so by configuring Keycloak to use the Google identity provider. Whenever you want to have a user authenticated against Google, you just need to use the Keycloak login page, and you will be redirected to Google. Here you have to authenticate against Google, and then you will be redirected back to Keycloak where it will create a new user in your Keycloak instance. You can then apply several permissions to this user, and you will be able to use it in your application. And, you can create an access token for this user against Google, so that you can perform actions on behalf of this user.

Wording

Keycloak uses specific words to describe objects and flows. Here are some explainations of them.

Table 1. Wordings in Keycloak
Object Description

Realm

A realm is a collection of users, clients, and groups.

Client

A client is a representation of an application that can use Keycloak to authenticate users.

User

A user is a representation of a person that can log into an application.

Group

A group is a collection of users.

Identity Provider

A system/website that can authenticate users. Famous examples are Google, Facebook, GitHub etc.

Principal

Mostly for Kerberos, this is a user account

So, from a top-down view:

  • a realm contains users, clients, and groups.

  • a Keycloak instance can have multiple realms (usually you have only two: a master realm, and your own application realm).

From a developer’s point of view:

  • you define a realm for your application

  • you create permissions for your application (what a user can do/is allowed to do)

Basics

Here we want to talk about the fundamentals.

JWT

The JWT Icon

The JSON Web Token, or jwt for short, is a string, having three base64 encoded parts, concattenated via a dot, as defined in RFC-7519. So, a JWT looks like:

abc123.def123.ghi123

The first part is the header json and tells about the encryption algorithm for the checksum (part 3).

Example:

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "n81WW5LhmLKgEyMcAxAhxUV_c6s9WEWnwngQY_-PXH0"
}
  • alg = the algorithm used to create the checksum

  • typ = the type of the token

  • kid = the key id/thumbprint of the public key, which is a reference to the key used to create the checksum


The second json defines the content or payload:

{
  "sub": "user01",
  "name": "Max Mustermann",
  "iat": 1516239022,
  "exp": 1516239322,
  "jti":"f7d3f86f-7841-41a9-96ef-8a6e3998676c"
  "iss":"https://172.21.0.100/auth/realms/MyRealm01",
  "aud": ["account", "my.client.01"],
  "typ": "Bearer",
  "azp": "my.client.01",
  "scope": "openid email profile",
  "session_state": "81b6e804-2414-42be-931d-ffecbcbb8616",
  "acr": "1",
  ...
}

Each root field in this object is called a claim. For example user.roles, or my-field-id. You can add claims by yourself if needed.

There are some pre-defined claims in jwt:

  • sub = the subject identifier, also known as the user id

  • name = the subject display name

  • iat = the time this token got created

  • exp = the time this token expires

  • jti = the unique identifier of this token

  • iss = the issuer of this token

  • aud = the audience of this token (basically, which client this token belongs to)

  • typ = the type of this token (Bearer)

  • azp = the authorized party of this token (basically, which client this token was created for)

  • acr = the authentication context class reference of this token

  • scope = the scopes this token was created for

As you can see, there are also additional "claims", like session_state and acr. This is a Keycloak specific claim. And you can add more claims by yourself. Like my-field-id in the example above.


The third part is a checksum of the header and the content:

checksum = HMACSHA256(base64urlEncode(header as string) + "." + base64urlEncode(payload as string), secret)

The checksum is simply added to both the base64 of the header and the content, added with a dot.


In Keycloak, the dot has a special definition: it defines sub objects in Json. So, user.roles with a value of "myrole01" will end up in a json object in the jwt as:

{
  "user": {
    "roles": "myrole01"
  }
}

So, be careful when you have dots in a name. If you still need dots, they need to be escaped with a backslash: \.


You can read more about JWT on their homepage.

Kerberos

Kerberos is a protocol to authenticate users over an unencrypted network, using encryption. Nowadays also the network is usually encrypted.

Directory Services

Here we talk about LDAP and Active Directory.

Keycloak

In this chapter I want to talk about Keycloak itself. All of its meaning, its wordings, procedures etc.

Permissions and Roles

The first thing we have to clarify is the concept of permissions and roles. And the security model of the application.

A role is a type of a user.

A permission can be something like can-read-newspage.

Flows

Flows define what authentication mechanisms can be used. Basically, what is required during authentication, like a password, or a specific token, or what fallback mechanisms are allowed during authentication. Also, steps like "send verification email" can be defined per flow. And, if these steps are "Required", or "Alternative".

Standard Flow

Keycloak Identity Provider 1 User DB 01 LDAP 01 AD 01 Website KC internal DB
Figure 1. The typical user browser auth flow

This is really the standard flow. The user uses a web browser on a website. To authenticate, the user is redirected from the website to the Keycloak login site. There the user authenticates against a configured source for the realm. For any result, the user gets redirected back to the website with the authentication result, be it success or failed.

Direct Access Grants Flow

Implicit Flow

Service Accounts Roles

OAuth2 Device Authorization Grant

OpenID Connect CIBA Grant

Clients

A client is an application that is allowed to work with Keycloak. It is associated to a Realm. In our later examples, one such client is our website. Or our backend server. Users must use a client to authenticate against a Realm in Keycloak.

User → Client → Keycloak → Realm → User Federation or Identity Provider

class A<T> <<singleton>> {
    {abstract} -int x
    {static} #void meta()
}

class B

A <|-- B

Clients can be public or confidential.

If public, the client can be accessed without a client secret. If confidential, the client gets a client secret that the caller must provide in order to use the client.

Roles

Roles are types of users, like Reader, Author, RaidLeader, Administrator, or SuperAdministrator etc. They all might have different permissions.

Realm Roles

These are roles belonging to a realm.

A role can have some attributes (key-value pairs).

Client Roles

Roles associated to a client.

Role mapping

Role mapping describes a way to map a role from an IDP or User Federation into a Realm Role (or Client Role).

This can be converting a given single string from the external token to a specific role within the realm.

Dealing with special characters

Sometimes, external roles might contain special characters. Like a dot. In this case, your role mapper must replace these characters with another character. Perhaps an underscore.

User Federation

This is just another buzzword for authenticating the user against a database. The database can either be:

  • a database (Postgresql?)

  • LDAP/ActiveDirectory

  • Kerberos

For failover, you can define a sequence of federations. By default, the first match wins. If all federations fail, the user is unauthenticated. This is usually done by having the Connection URL using spaces between the connection strings. At least for the LDAP.

Be aware that Keycloak uses an internal database to store all of its configurations, as well as user accounts based on the external reference. Which means, if User A is known via an LDAP lookup, Keycloak will create an internal account for this user to store the reference to LDAP, as well as to allow adding additional keycloak related attributes to this account.

Using Kerberos

You can use Kerberos for user and service authentication against Keycloak. For this, the Kerberos server must exist, have a principal, and a keytab.

For Kerberos, you need to provide some information about the Kerberos Realm and the server principal (as well as its keytab file).

  • the Kerberos realm; example: DS2.LAN (yes, uppercase!!)

  • the server principal; example: HTTP/www.ds2@DS2.LAN (the service identifier HTTP, then the dns name where the Keycloak server can be found, followed by the realm name)

  • the keytab file of this principal; can be generated when setting up the principal in Kerberos

Note
The keytab file contains the symmetric key of the principal, and the signing key of the realm.

Using LDAP

You can use an LDAP server for user authentication. Since Active Directory is a Windows server, you can use the Active Directory server as an LDAP server.

Integration into Keycloak

LDAP vs LDAPS

Using ActiveDirectory

This is Microsofts answer to LDAP, also containing Kerberos interfaces. Since an AD server is usually a domain controller, it also runs a DNS server, IIS etc.

AD defines a domain name, for example ds2. This can be also then used, together with the dns name, for the Kerberos realm. For example, if your network domain is called fritz.box, your Kerberos realm might be known as DS2.FRITZ.BOX (be aware of the uppercase name for Kerberos realms!).

In the AD you define users and groups.

There is a special user called krbtgt which acts as the Kerberos "user" (or "Key Distribuction Center Service Account") to receive ticket-granting-ticket queries. This user is deactivated by default to avoid logging in as this user. Since this is a system user, there are no issues here.

Via PowerShell you can create the required keytab file for Kerberos if you need one. In case of Keycloak, it depends on whether Kerberos authentication is required or not.

To show all service principals related to a user, run:

setspn -l USERNAME
# for example: setspn -l administrator

Scopes

Scopes are units that contain specific attributes. In Keycloak, a scope defines what attributes a client can get and/or request. It defines a set of mappers.

Client Scopes

Client scopes are scopes that are specific to clients only. That means, a client can have a scope that returns specific data back to the caller that usually are not needed in realm scope.

Configure Keycloak

In this chapter, we want to discuss how to configure Keycloak.

Setting timeouts to connections

There are several ways to set timeouts to connections. You have the initial connection from your client to the server. And from within the server to other IdPs. And database connections, ldap connections etc.

So, famous flow is:

You → Keycloak → IdP → Database/LDAP/etc.

You have the timeout between you and Keycloak. Then internally Keycloak to speak to the Idp. And the Idp may have another timeout accessing its database. So, quite some things to configure here. Usually you want the last part of this chain to have a smaller timeout than the first ones.

When talking between you and Keycloak, or Keycloak to another Idp, there is an http client involved.

Here is a list of properties that can be set:

  • spi-connections-http-client-default-socket-timeout-millis (5000) the default http socket timeout

  • spi-connections-http-client-default-connection-timeout-millis (5000) the default http connection timeout

  • spi-connections-http-client-default-connection-request-timeout-millis (5000) the default http connection request timeout

  • spi-connections-http-client-default-connection-pool-size (100) the default http connection pool size

Some properties can be also represented as environment variables. Usually, you take the property name, replace - with an underscore and convert it to upper case, prefixing it with KC_. So, to match one property from above, you would use KC_SPI_CONNECTIONS_HTTP_CLIENT_DEFAULT_SOCKET_TIMEOUT_MILLIS, setting it to 10000.

Setting timeouts for LDAP

Besides that you can configure the timeouts via API, you can also configure them via the admin console. Just go to the realm settings, and then to the LDAP settings (in user federations). There you can set the Connection Timeout for the specific ldap user federation.

Running Keycloak

The very simplest way to run Keycloak is to run it as container.

Note
I prefer Podman over Docker. In my examples I will use Podman, but you can use Docker as well.
# pull the image
podman pull quay.io/keycloak/keycloak:24.0

# run the image
podman run --rm -d -p 18080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=myadminpw quay.io/keycloak/keycloak:24.0 start-dev

Now you can open Keycloak at http://localhost:18080/.

Using Keycloak for your application

So, you have an application. And you want that people can sign in to it and do some stuff they are allowed to do. That means, you need to put these users into specific groups. And these groups get specific permissions. Your application knows about the permissions and can either allow or deny specific actions the user can do. Then you should get a server that can authenticate users and get their permissions. Something like, I don’t know: Keycloak.

So, this chapter deals about setting up Keycloak for your application.

Our Angular App with Keycloak

For our sample app we will use Angular, and Keycloak as our authentication provider. This will be a simple guild web site, where people can login, create posts, and comment on them. Some users might be able to change the layout, or edit posts of others.

Using Rust with Keycloak

In this chapter we will use the Rust language to interact with Keycloak. Especially by using Actix-Web for a simple REST CRUD API.

The API of Keycloak

In this chapter we will talk about how to configure Keycloak remotely via its own API.

Sources

Here is a list of some of the web sites I used to gather information from:

All the names here are owned by their respective owners.

I am not a developer of Keycloak, I am just a user who has a Keycloak server.

Version of this document: ebc55c28638fe7f56fc8841f16c7ed843f59ce53