How to customize Keycloak themes
Tags: keycloak, webdev, tutorial
Published: 2022-04-21 11:55:52

In this insight, you will learn how Keycloak Themes are structured and how to come up with your own custom theme.

Because we believe that learning is best done when putting everything into practices, we will start off by setting up a development environment. Right after, we will go over the types of themes and the folder structure. Closing with how to add customization and build your own Keycloak theme.

Before we get started with all the details, a quick recap of what Keycloak is and why we care about it.

## What is Keycloak?

Keycloak is an open-source identity and access management or IAM solution, that can be used as a third-party authorization server to manage your web or mobile applications' authentication and authorization requirements.

It lifts the heavy weight of implementing a stable and secure user authorization and authentication, from the shoulders of developers.

At [TRIGO](https://trigodev.com), we use it for all of our projects. It saved tons of time and money. Kept us staying sane when integrating AuthN/AuthZ into an application. We love Keycloak.

Now let's dive right into it.

## Setting up a development environment

You could either download Keycloak and run it natively on your machine, or spin up some container using docker or podman.

We at [TRIGO](https://trigodev.com) are heavily into containerization. Therefore, we will use the second option for this tutorial.

To make things even simpler for you, we have prepared a fully functional setup as [Git repository](https://github.com/trigo-at/keycloak-theme-development).

> Before proceeding with this tutorial, please take your time to check out the repository and follow the instructions found in the README file. If you got any questions, please feel free to [open an issue](https://github.com/trigo-at/keycloak-theme-development/issues/new).

## Theme types

With a single theme, you can provide one or more types of customization.

An overview:

| Type    | Description                                                                   | Location of the demo repository                                                                             |
| ------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Common  | Files (resources) shared along all theme types                                | `themes/keycloak-provided-themes/keycloak/common`                                                        |
| Account | All things related to the Account management (self-service) area.             | `themes/keycloak-provided-themes/base/account` and `themes/keycloak-provided-themes/keycloak.v2/account` |
| Admin   | The admin console. Yes, the very extensive area can be customized too.        | `themes/keycloak-provided-themes/base/admin` and `themes/keycloak-provided-themes/keycloak.v2/admin`     |
| Emails  | Everything you need to customize Emails sent by Keycloak                      | `themes/keycloak-provided-themes/base/email`                                                             |
| Login   | User-facing public pages like login, password reset and so on.                | `themes/keycloak-provided-themes/base/login` and `themes/keycloak-provided-themes/keycloak/login`        |
| Welcome | The welcome page shown when spinning up Keycloak and opening its landing page | `themes/keycloak-provided-themes/keycloak/welcome`                                                       |

**Hint:** Instructions on [how to configure a theme](https://www.keycloak.org/docs/latest/server_development/index.html#configuring-a-theme) can be found in the Keycloak Documentation.

## Structure of a theme folder

Every theme must consist of one or more type related subdirectories.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7lli3uxp2xmb9uiy9lr.png)

It's a 1:1 reference to the theme types mentioned above.

## Structure of a theme type folder

Every theme type folder must have at least a `theme.properties` file. It contains basic instructions for Keycloak.

Furthermore, it consists of one or more of the following folders

| Folder    | Description                                                                                        |
| --------- | -------------------------------------------------------------------------------------------------- |
| messages  | Contains one or more messages_XX.properties files. They are part of the i18n mechanism of Keycloak |
| resources | Every image, CSS or JavaScript file that is required to power the theme type is found here.        |

**Note:** The email type is a little different. It contains an HTML and text folder containing the email templates for HTML and text emails. All as FTL files.

Besides that, a theme type folder usually comes with many template files (.ftl file ending). They represent all the different pages Keycloak has.

## All your base belongs to me. Theme Inheritance explained

You might have noticed that for most types, there are multiple places where you can find related files. That's because Keycloak themes are built with inheritance in mind. Everything is (or it can be) based on `base` (phun intended!). You could, theoretically, start from scratch, but we don't recommend that unless you have a special use case. It's just a lot of work to provide everything you need for a fully functional theme.

### Theme type entry point: theme.properties

Let's have a look at the entry point of the login type.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f4ao1r3k26fxftd2i04q.png)

_This is from themes/keycloak-provided-themes/keycloak/login_

The first line of `theme.properties` is:

```
parent=base
```

With this, we instruct Keycloak to inherit our login type from the base theme. We can then focus on the things we like to change instead of starting from zero.

## FTL - Faster than light or Freemarker

Freemarker is a template language like Pug, Mustache or EJS. If you are familiar with the primary template language of your ecosystem, you should be familiar with the core concepts of freemarker too.

I still recommend going through the [“Template Author Guide”](https://freemarker.apache.org/docs/dgui_quickstart.html). The Keycloak Login Theme makes heavy use of the FTL inheritance features. So better be prepared to dig in deep.

## Data Models for your templates

Keycloak uses numerous data models within their template files. They are - let just put it that way - not very well documented.

To get at least a basic understanding, these two files from the Keycloak Source Code are a good starting point:

### For Theme Type: Login

```
https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
```

### For Theme Type: Account

```
https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java
```

## What other tech is included?

For the time of writing this insight, Keycloak 17 is the newest version available. There are announcements that the current angular1 based admin and account theme is replaced by a React-based solution anytime soon. Keycloak 15 already has an early version of that included. It can be found as `keycloak.v2` theme here: `themes/keycloak-provided-themes/keycloak.v2`

The Login part of the theme uses an earlier version of the Patternfly Framework. Files:

```
themes/keycloak-provided-themes/keycloak/common/resources/web_modules/@patternfly
```

Since there is no version information available, it's hard to tell which version of Patternfly it is, but all required resources are included.

v4 of Patternfly is a [remarkable framework found here](https://www.patternfly.org/v4/).

## How to customize a theme type?

For all of you who, me included, are like: Ok Patternfly is cool and what not , but I want to bring my own stuff to the table. Tailwind, Vue, Svelte, Chakra, ... just a little more patience.

Before we explore how to create a custom theme with your favorite tech stack, I think it's important to understand the structure of the default theme.

For this tutorial, I will focus on the login theme type further on. I assume that that's the type most of you want to customize anyway. Also, when you understand that part of a theme, the e.g. account part is a piece of cake for you.

The first file you should examine closer is `template.ftl`. It contains the basic HTML page structure and all <#nested> instructions that are used in the various templates. It defines a macro that is used in pages like login, register, login-reset-password, …

Speaking of the different templates. A quick excursion on what files are the more relevant ones:

### Login theme type most relevant templates

| Folder                    | Description             |
| ------------------------- | ----------------------- |
| login.ftl                 | Username/Password login |
| register.ftl              | User registration       |
| login-reset-password.ftl  | Password Reset          |
| login-update-password.ftl | Password Update         |
| login-otp.ftl             | OTP/2FA login           |
| error.ftl                 | Error page              |

### Back to customizing the login theme type

Within the FTL templates various data-models are used as mentioned above. It's beyond the scope of this tutorial to explain every detail. I strongly recommend to set aside some time to go through ALL the files and explore how the various properties are used and for what purpose.

If you got any questions, please feel free to drop me an email at david@trigodev.com

### CSS Classes confusion

Said that, there is one detail I like to explain a bit. How CSS classes are handled. It was a source of confusion for me when starting with Keycloak theme development. CSS Classes are set via properties that are defined in the `theme.properties` file of the login theme type.

**Example:**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ns58ppnvsnqy4c2rwug.png)

I don't get the reason behind that decision. I guess the idea was to provide a way to customize the CSS classes in a central way. It was one of the first things I dropped when building the first themes for ourselves.

### Included Messages for i18n

Let's assume you have added some new i18n message to one of the message_xx.properties files in the messages' folder. For example, some marketing information you want to include on the login page.

Freemarker provides a `msg` function to include i18n messages.

Note: It will refer to the language currently selected by the user. Keycloak uses Browser information to determine the language, but only if the language is configured.

**Example:**

```
${msg("doForgotPassword")}
```

## Some notes on security

All things you know about web security are relevant for Keycloak themes too. Keep in mind that you are basically building a website (or web application for the account/admin theme type).

Therefore, just a few short notes on security:

### Sanitizing all user-generated content

Keycloak provides a `kcSanitize` function to sanitize HTML content. I highly recommend using that function when including user provided HTML content in any way.

**Example:**

```
${kcSanitize(message.summary)?no_esc}
```

[Code found here.](https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/theme/KeycloakSanitizerMethod.java)

### CSRF Protection

According to the OAUTH2 Specification, CSRF Protection is done via a state query parameter. Keycloak handles that for us via the `url.loginAction` property used as form action

```
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
```

Don't change that unless you know exactly what you are doing here.

A more detailed explanation on how the state parameter helps to prevent CSRF attacks [can be found here](https://auth0.com/docs/secure/attack-protection/state-parameters).

## Bring your own stuff

As you might have guessed, besides learning all the details about the tech stack involved and some innards about the data-model used, there is nothing special to a Keycloak theme. It's just web development. So, why not bring your well-known framework of choice to the table? The good news is that, there is no reason not to go down that road.

In fact, we do that by using Tailwind to style our themes.

I've included an example to the Git Repository. You are welcome to use that as a starting point (see themes folder).

Note: The themes are mapped into the `docker-compose.yml` to make them visible to Keycloak. You have to add your own theme to that by duplicating and adopt this line in the `docker-compose.yml`

```
./themes/tailwind-example/:/opt/jboss/keycloak/themes/tailwind-example/
```

## Recap

We have learned how Keycloak themes are structured, what files are important, how inheritance works for themes and how to get started with custom themes.

I've tried to add as many lessons learned as possible. If anything isn't super clear or missing, please point that out.

Again, if you got any questions, please reach out to me.