297 lines
15 KiB
XML
Executable file
297 lines
15 KiB
XML
Executable file
<chapter id="themes">
|
|
<title>Themes</title>
|
|
|
|
<para>
|
|
Keycloak provides theme support for web pages and emails. This allows customizing the look
|
|
and feel of end-user facing pages so they can be integrated with your applications.
|
|
</para>
|
|
|
|
<section>
|
|
<title>Theme types</title>
|
|
<para>
|
|
A theme can support several types to customize different aspects of Keycloak. The types currently available
|
|
are:
|
|
<itemizedlist>
|
|
<listitem>Account - Account management</listitem>
|
|
<listitem>Admin - Admin console</listitem>
|
|
<listitem>Email - Emails</listitem>
|
|
<listitem>Login - Login forms</listitem>
|
|
<listitem>Welcome - Welcome pages</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Configure theme</title>
|
|
<para>
|
|
All theme types, except welcome, is configured through <literal>Keycloak Admin Console</literal>. To change
|
|
the theme used for a realm open the <literal>Keycloak Admin Console</literal>, select your realm
|
|
from the drop-down box in the top left corner. Under <literal>Settings</literal> click on <literal>Theme</literal>.
|
|
</para>
|
|
<para>
|
|
To set the theme for the <literal>master</literal> Keycloak admin console set the admin console theme for
|
|
the <literal>master</literal> realm. To set the theme for per realm admin access control set the admin console
|
|
theme for the corresponding realm.
|
|
</para>
|
|
<para>
|
|
To change the welcome theme you need to edit <literal>standalone/configuration/keycloak-server.json</literal>
|
|
and add <literal>welcomeTheme</literal> to the theme element, for example:
|
|
<programlisting>
|
|
"theme": {
|
|
...
|
|
"welcomeTheme": "custom-theme"
|
|
}
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Default themes</title>
|
|
<para>
|
|
Keycloak comes bundled with default themes in <literal>standalone/configuration/themes</literal>. You should
|
|
not edit the bundled themes directly. Instead create a new theme that extends a bundled theme.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Creating a theme</title>
|
|
<para>
|
|
A theme consists of:
|
|
<itemizedlist>
|
|
<listitem><ulink url="http://freemarker.org">FreeMarker</ulink> templates</listitem>
|
|
<listitem>Stylesheets</listitem>
|
|
<listitem>Scripts</listitem>
|
|
<listitem>Images</listitem>
|
|
<listitem>Message bundles</listitem>
|
|
<listitem>Theme properties</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
A theme can extend another theme. When extending a theme you can override individual files (templates, stylesheets, etc.).
|
|
The recommended way to create a theme is to extend the base theme. The base theme provides templates
|
|
and a default message bundle. If you decide to override templates bear in mind that you may need to update
|
|
your templates when upgrading to a new release to include any changes made to the original template.
|
|
</para>
|
|
<para>
|
|
Before creating a theme it's a good idea to disable caching as this makes it possible to edit theme resources
|
|
without restarting the server. To do this open <literal>../standalone/configuration/keycloak-server.json</literal>
|
|
for <literal>theme</literal> set <literal>staticMaxAge</literal> to <literal>-1</literal> and
|
|
<literal>cacheTemplates</literal> and <literal>cacheThemes</literal> to <literal>false</literal>. For example:
|
|
<programlisting>[<![CDATA[
|
|
"theme": {
|
|
"default": "keycloak",
|
|
"staticMaxAge": -1,
|
|
"cacheTemplates": false,
|
|
"cacheThemes": false,
|
|
"folder": {
|
|
"dir": "${jboss.server.config.dir}/themes"
|
|
}
|
|
},
|
|
]]></programlisting>
|
|
Remember to re-enable caching in production as it will significantly impact performance.
|
|
</para>
|
|
<para>
|
|
To create a new theme create a directory for the theme in <literal>.../standalone/configuration/themes</literal>.
|
|
The name of the directory should be the name of the theme. For example to create a theme called <literal>example-theme</literal>
|
|
create the directory <literal>.../standalone/configuration/themes/example-theme</literal>. Inside the theme
|
|
directory you then need to create a directory for each of the types your theme is going to provide. For example
|
|
to add the login type to the <literal>example-theme</literal> theme create the directory
|
|
<literal>.../standalone/configuration/themes/example-theme/login</literal>.
|
|
</para>
|
|
<para>
|
|
For each type create a file <literal>theme.properties</literal> which allows setting some configuration for
|
|
the theme, for example what theme it overrides and if it should import any themes. For the above example we
|
|
want to override the base theme and import common resources from the Keycloak theme. To do this create the
|
|
file <literal>.../standalone/configuration/themes/example-theme/login/theme.properties</literal> with the
|
|
following contents:
|
|
<programlisting>[<![CDATA[
|
|
parent=base
|
|
import=common/keycloak
|
|
]]></programlisting>
|
|
</para>
|
|
<para>
|
|
You have now created a theme with support for the login type. To check that it works open the admin console.
|
|
Select your realm and click on <literal>Themes</literal>. For <literal>Login Theme</literal> select
|
|
<literal>example-theme</literal> and click <literal>Save</literal>. Then open the login page for the realm.
|
|
You can do this either by login through your application or by opening <literal>http://localhost:8080/realms/<realm name>/account</literal>.
|
|
</para>
|
|
<para>
|
|
To see the effect of changing the parent theme, set <literal>parent=keycloak</literal> in <literal>theme.properties</literal>
|
|
and refresh the login page. To follow the rest of the documentation set it back to <literal>parent=base</literal>
|
|
before continuing.
|
|
</para>
|
|
<section>
|
|
<title>Stylesheets</title>
|
|
<para>
|
|
A theme can have one or more stylesheets, to add a stylesheet create a file inside <literal>resources/css</literal>
|
|
(for example <literal>resources/css/styles.css</literal>) inside your theme folder. Then registering it
|
|
in <literal>theme.properties</literal> by adding:
|
|
</para>
|
|
<programlisting>styles=css/styles.css</programlisting>
|
|
<para>
|
|
The <literal>styles</literal> property supports a space separated list so you can add as many
|
|
as you want. For example:
|
|
</para>
|
|
<programlisting>styles=css/styles.css css/more-styles.css</programlisting>
|
|
For the example-theme above add <literal>example-theme/login/resources/css/styles.css</literal> with the
|
|
following content:
|
|
<programlisting>[<![CDATA[
|
|
#kc-form {
|
|
background-color: #000;
|
|
color: #fff;
|
|
padding: 20px;
|
|
}]]></programlisting>
|
|
Then edit <literal>example-theme/login/theme.properties</literal> and add <programlisting>styles=css/styles.css</programlisting>.
|
|
Refresh the login page to see your changes. It's not pretty, but you can see how easily you can modify the
|
|
styles for your theme.
|
|
</section>
|
|
<section>
|
|
<title>Scripts</title>
|
|
<para>
|
|
A theme can have one or more scripts, to add a script create a file inside <literal>resources/js</literal> (for example <literal>resources/js/script.js</literal>)
|
|
inside your theme folder. Then registering it in <literal>theme.properties</literal> by adding:
|
|
</para>
|
|
<programlisting>scripts=js/script.js</programlisting>
|
|
<para>
|
|
The <literal>scripts</literal> property supports a space separated list so you can add as many
|
|
as you want. For example:
|
|
</para>
|
|
<programlisting>scripts=js/script.js js/more-script.js</programlisting>
|
|
</section>
|
|
<section>
|
|
<title>Images</title>
|
|
<para>
|
|
To make images available to the theme add them to <literal>resources/img</literal>. They can then be used
|
|
through stylesheets. For example:
|
|
</para>
|
|
<programlisting>body {
|
|
background-image: url('../img/image.jpg');
|
|
}</programlisting>
|
|
<para>
|
|
Or in templates, for example:
|
|
</para>
|
|
<programlisting><img src="${url.resourcesPath}/img/image.jpg"></programlisting>
|
|
</section>
|
|
<section>
|
|
<title>Messages</title>
|
|
<para>
|
|
Text in the templates are loaded from message bundles. A theme that extends another theme will inherit
|
|
all messages from the parents message bundle, but can override individual messages. For example to replace
|
|
<literal>Username</literal> on the login form with <literal>Your Username</literal> create the file
|
|
<literal>messages/messages.properties</literal> inside your theme folder and add the following content:
|
|
</para>
|
|
<programlisting>username=Your Username</programlisting>
|
|
</section>
|
|
<section>
|
|
<title>Modifying HTML</title>
|
|
<para>
|
|
Keycloak uses <ulink url="http://freemarker.org">Freemarker Templates</ulink> in order to generate HTML.
|
|
These templates are defined in <literal>.ftl</literal> files and can be overriden from the base theme.
|
|
Check out the Freemarker website on how to form a template file. To override the login template for the
|
|
<literal>example-theme</literal> copy <literal>../standalone/configuration/themes/base/login/login.ftl</literal>
|
|
to <literal>../standalone/configuration/themes/example-theme/login</literal> and open it in an editor. After
|
|
the first line (<#import ...>) add <literal><h1>HELLO WORLD!</h1></literal> then refresh
|
|
the page.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Deploying themes</title>
|
|
<para>
|
|
Themes can be deployed to Keycloak by copying the theme directory to <literal>../standalone/configuration/themes</literal>
|
|
or it can be deployed as a module. For a single server or during development just copying the theme is fine, but
|
|
in a cluster or domain it's recommended to deploy as a module.
|
|
</para>
|
|
<para>
|
|
To deploy a theme as a module you need to create an jar (it's basically just a zip with jar extension) with
|
|
the theme resources and a file <literal>META/keycloak-themes.json</literal> that describes the themes contained
|
|
in the archive. For example <literal>example-theme.jar</literal> with the contents:
|
|
<itemizedlist>
|
|
<listitem>META-INF/keycloak-themes.json</listitem>
|
|
<listitem>theme/example-theme/login/theme.properties</listitem>
|
|
<listitem>theme/example-theme/login/login.ftl</listitem>
|
|
<listitem>theme/example-theme/login/resources/css/styles.css</listitem>
|
|
</itemizedlist>
|
|
The contents of META-INF/keycloak-themes.json in this case would be:
|
|
<programlisting>[<![CDATA[
|
|
{
|
|
"themes": [{
|
|
"name" : "example-theme",
|
|
"types": [ "login" ]
|
|
}]
|
|
}
|
|
]]></programlisting>
|
|
As you can see a single jar can contain multiple themes and each theme can support one or more types.
|
|
</para>
|
|
<para>
|
|
The deploy the jar as a module to Keycloak you can either manually create the module or use <literal>jboss-cli</literal>.
|
|
It's simplest to use <literal>jboss-cli</literal> as it creates the required directories and module descriptor
|
|
for you. To deploy the above jar <literal>jboss-cli</literal> run:
|
|
<programlisting>[<![CDATA[
|
|
KEYCLOAK_HOME/bin/jboss-cli.sh --command="module add --name=org.example.exampletheme --resources=example-theme.jar"
|
|
]]></programlisting>
|
|
If you're on windows run <programlisting>KEYCLOAK_HOME/bin/jboss-cli.bat</programlisting>.
|
|
</para>
|
|
<para>
|
|
This command creates <literal>modules/org/example/exampletheme/main</literal> containing <literal>example-theme.jar</literal>
|
|
and <literal>module.xml</literal>.
|
|
</para>
|
|
<para>
|
|
Once you've created the module you need to register it with Keycloak do this by editing
|
|
<literal>../standalone/configuration/keycloak-server.json</literal> and adding the module to <literal>theme/module/modules</literal>. For example:
|
|
<programlisting>[<![CDATA[
|
|
"theme": {
|
|
...
|
|
"module": {
|
|
"modules": [ "org.example.exampletheme" ]
|
|
}
|
|
}
|
|
]]></programlisting>
|
|
</para>
|
|
<para>
|
|
If a theme is deployed to <literal>../standalone/configuration/themes</literal> and as a module the first
|
|
is used.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>SPIs</title>
|
|
<para>
|
|
For full control of login forms and account management Keycloak provides a number of SPIs.
|
|
</para>
|
|
<section>
|
|
<title>Account SPI</title>
|
|
<para>
|
|
The Account SPI allows implementing the account management pages using whatever web framework or templating
|
|
engine you want. To create an Account provider implement <literal>org.keycloak.account.AccountProviderFactory</literal>
|
|
and <literal>org.keycloak.account.AccountProvider</literal>.
|
|
</para>
|
|
<para>
|
|
Once you have deployed your account provider to Keycloak you need to configure <literal>keycloak-server.json</literal> to specify which provider should be used:
|
|
<programlisting>
|
|
"account": {
|
|
"provider": "custom-provider"
|
|
}
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Login SPI</title>
|
|
<para>
|
|
The Login SPI allows implementing the login forms using whatever web framework or templating
|
|
engine you want. To create a Login forms provider implement <literal>org.keycloak.login.LoginFormsProviderFactory</literal>
|
|
and <literal>org.keycloak.login.LoginFormsProvider</literal> in <literal>forms/login-api</literal>.
|
|
</para>
|
|
<para>
|
|
Once you have deployed your account provider to Keycloak you need to configure <literal>keycloak-server.json</literal> to specify which provider should be used:
|
|
<programlisting>
|
|
"login": {
|
|
"provider": "custom-provider"
|
|
}
|
|
</programlisting>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
</chapter>
|