Tools

Keycloak in Docker #3 – How to customise Keycloak themes

Keycloak allows us to customise its themes. This enables us to provide a user interface that remains consistent across all of our applications, ensuring a better user experience for everyone.

Prerequisites

docker ps
CONTAINER ID   IMAGE                      PORTS                                                 NAMES
774a1d259bf9   jboss/keycloak:15.0.2      8443/tcp, 0.0.0.0:8024->8080/tcp, :::8024->8080/tcp   keycloakindocker_keycloak_1
6f10181d012b   postgres:14.1-alpine       0.0.0.0:5433->5432/tcp, :::5433->5432/tcp             keycloakindocker_keycloakdb_1

Disable theme caching

The Keycloak documentation recommends disabling the cache for themes while working on creating our custom theme:

While creating a theme it’s a good idea to disable caching as this makes it possible to edit theme resources directly from the themes directory without restarting Keycloak. To do this edit standalone.xml. (…) Remember to re-enable caching in production as it will significantly impact performance.

https://www.keycloak.org/docs/16.1/server_development/#creating-a-theme

Therefore, we’re going to write a script that disables caching themes and run it as a startup script for our container. First, I’m going to add the keycloak/scripts/disable-theme-cache.cli file to my repository:

embed-server --std-out=echo --server-config=standalone-ha.xml
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=staticMaxAge,value=-1)
stop-embedded-server

Next, I’ll provide the script as a volume for the container’s startup-scripts directory:

version: '3.3'
services:
  keycloak:
    image: …
    ports:
      …
    environment:
      …
    volumes:
      …
      - ./keycloak/scripts/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
    networks:
      …
    depends_on:
      …
…

You can find the work presented in this section in the 83e26988848587700ff453bb1ac80bb0c64feda5 commit.

Customising

A Keycloak theme contains styles and assets for different groups of pages – called types in the documentation:

A theme can provide one or more types to customise different aspects of Keycloak. The types available are:

Account – used to style user profile views;

Admin – with styles for the admin UI;

Email – for styling emails;

Login – used to customise login forms (login, register, forgot password);

Welcome – the Welcome page.

https://www.keycloak.org/docs/16.1/server_development/#theme-types

For the sake of simplicity, I’m going to customise only two types – Login and Account. In the first place, I’m going to create an empty directory for my theme:

To create a new theme start by creating a new directory in the themes directory. The name of the directory becomes the name of the theme. For example to create a theme called mytheme create the directory themes/mytheme.

https://www.keycloak.org/docs/16.1/server_development/#creating-a-theme

Comsequently, I’m going to create the backend/docker/keycloak/themes/custom directory as I want to name my theme custom. Furthermore, I’m going to mount it as a volume in my keycloak service:

version: '3.3'
services:
  keycloak:
    image: …
    ports:
      …
    environment:
      …
    volumes:
      - ./keycloak/themes/custom:/opt/jboss/keycloak/themes/custom
      …
    networks:
      …
    depends_on:
      …
…

As a result, we’ll see my custom theme among other Keycloak themes after restarting the service:

Customise Keycloak theme for the login type

Of course, the custom theme is still empty and we can’t apply it. In other words, all Keycloak pages use default styles. We’re going to start our customisation from the login type. Visit: http://localhost:8024/auth/realms/Example-Realm/account link to examine the standard Keycloak login type:

I’m going to create the login folder inside the custom directory. However, I’m not going to fabricate my theme completely from scratch. I’ll follow the documentation on creating a new theme and extend the Keycloak theme:

Most likely you will want to extend the Keycloak theme, but you could also consider extending the base theme if you are significantly changing the look and feel of the pages. The base theme primarily consists of HTML templates and message bundles, while the Keycloak theme primarily contains images and stylesheets.

https://www.keycloak.org/docs/16.1/server_development/#creating-a-theme

For reference, this is the structure of the login folder that we’re going to create:

Change background image

First, I want to use a different picture as a page background. Therefore, I’m going to create the custom/login/resources/img folder and download the new picture there (pexels-pixabay-358312.jpg).

Change login styles

Next, I’m going to override some styles in the custom/login/resources/styles.css:

/*backend/docker/keycloak/themes/custom/login/resources/css/styles.css*/
:root {
    --pf-global--primary-color--100: #ff0054;
    --pf-global--primary-color--200: #d60248;
    --default-background-color: #97A1CDFF;
    --link-hover-color: #02679a;
}

.login-pf body {
    background-image: url('../img/pexels-pixabay-358312.jpg'),
    linear-gradient(135deg, var(--default-background-color) 0%, #A96699FF 100%);
}

.login-pf a:hover {
    color: var(--link-hover-color);
    text-decoration: none;
}

.pf-c-form-control {
    --pf-global--primary-color--100: unset;
}

Generally speaking, my styles replace the default picture and provide a gradient as a fallback background. Moreover, I’m changing the primary colour (providing the lighter and darker shades) and the colour and text decoration of links for the hover pseudo-class. Last but not least, I’m resetting the default primary colour for forms as it would override the one I set in the :root section.

Configure the custom login type

In order to include our styles in the theme, we need to create the custom/login/theme.properties file. Each type has to have this file as the source of its configuration. Since we’re extending the login type from the Keycloak theme, let’s see the theme.properties file for our parent as a reference:

As we can see, we definitely need to override the parent property for our theme. We also can’t forget to include the Keycloak stylesheets before providing our own:

To include the styles from the parent theme you need to load the styles from that theme as well.

https://www.keycloak.org/docs/16.1/server_development/#stylesheets

The resulting theme.properties file for the login type for the custom theme looks as follow:

#backend/docker/keycloak/themes/custom/login/theme.properties
parent=keycloak
styles=css/login.css css/tile.css css/styles.css

Enable the customised type

Restart the service so that the volume with our custom theme is mounted (if you haven’t restarted it after creating the volume). Login as admin to the admin panel (http://localhost:8024/auth/) and choose the custom theme as a value for the Login Theme property in the realm settings:

Verify changes of the login type

Now, visit the: http://localhost:8024/auth/realms/Example-Realm/account page and verify that the new theme is used instead of the default one:

Background photo by Pixabay from Pexels

You can see the work presented in this article in the bbce63fb404cb5eade3019da8ae7a95d229a8bf0 commit.

Customise Keycloak theme for the account type

You can see the default keycloak.v2 theme used for the account type on the image below:

To keep this section concise, I’m not going to include the content of the default keycloak.v2 theme. You can find it in the keycloak container under the opt/jboss/keycloak/themes/keycloak.v2 path:

For reference, this is the structure of the account folder that we’re going to create:

On top of customising some styles in the layout.css file, I’m going to provide my own logo and favicon.

Change account styles

Since I’m going to extend the keycloak.v2 theme I’ll mirror its directory structure. First, I’m going to override some styles in my custom/account/resources/public/layout.css:

/*backend/docker/keycloak/themes/custom/account/resources/public/layout.css*/
:root {
    --pf-global--primary-color--100: #ff0054;
    --pf-global--primary-color--200: #d60248;
    --pf-global--primary-color--dark-100: var(--pf-global--primary-color--200);
}

.pf-c-data-list {
    --pf-global--primary-color--100: unset;
}

.pf-c-button {
    --pf-c-button--m-secondary--hover--Color: var(--pf-global--primary-color--200);
    --pf-c-button--m-secondary--hover--BorderColor: var(--pf-c-button--m-secondary--hover--Color);
}

In genral, I’m going to change the primary colour, unset a keycloak class that would override it and update button styles. Please note that we have disabled theme caching so trying different styles won’t consume much of your time 🙂

Configure the custom account type

For the configuration extending the keycloak.v2 theme I’m going to provide the following theme.properties file:

#backend/docker/keycloak/themes/custom/account/theme.properties
parent=keycloak.v2
favIcon=/public/favicon.png

That’s all we need to do to prepare the account type for our custom theme.

Enable the customised type

Again, login as admin to the admin panel (http://localhost:8024/auth/) and choose the custom theme as a value for the Accont Theme property in the realm settings:

Verify changes of the account type

Now, visit the: http://localhost:8024/auth/realms/Example-Realm/account page, login as one of the realm users and verify that the new theme is used instead of the default one:

You can see the work presented in this article in the 861c7b3961cf3ab399fff091d92e827070532630 commit.

Learn more on how to customise Keycloak themes

Photo by Ezekixl Akinnewu from Pexels

little_pinecone

View Comments

  • Thank you this information. Most of the "customise theme for Keycloak" posts are bizarre! This information works with the official docs and fills in the missing information there. Much appreciated.

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago