1. 概述

Keycloak 是一款开源的身份与访问管理(IAM)解决方案,常作为第三方授权服务器,用于管理 Web 或移动应用的认证与授权逻辑。

本文重点讲解 如何定制 Keycloak 服务器的主题(Theme),从而让面向最终用户的登录、注册、账户管理等页面拥有符合自身产品风格的视觉体验。

我们将以独立部署的 Keycloak 服务器为背景展开说明,后续再延伸到嵌入式(Embedded)场景的应用。

本文基于之前两篇文章构建:《Spring Boot 集成 Keycloak 快速入门》《将 Keycloak 嵌入 Spring Boot 应用》。如果你是初次接触,建议先阅读这两篇打基础。


2. Keycloak 中的主题机制

2.1. 默认主题

Keycloak 自带几个预置主题,打包在发行版中。

对于独立部署的服务器,这些主题位于 lib/lib/main/org.keycloak.keycloak-themes-20.0.3.jartheme 目录下,可用任意 ZIP 工具打开查看:

  • **base**:基础骨架主题,包含 HTML 模板和国际化资源包(message bundles),所有其他主题(包括自定义的)都默认继承它
  • **keycloak**:经典主题,包含页面样式和图片资源;若未指定自定义主题,系统默认使用此主题
  • **keycloak.v2**:基于 React 的新版管理控制台主题;旧版控制台已弃用,将在 Keycloak 21 中移除

⚠️ 强烈不建议直接修改这些内置主题。正确的做法是创建一个新主题,继承上述某个主题进行扩展。

创建自定义主题的正确姿势:在 themes 目录下新建一个文件夹,比如叫 custom。如果想从零开始,可以复制 base 的内容;如果只是微调样式,建议从 keycloak 目录复制,省时省力。

2.2. 主题类型

Keycloak 支持五种主题类型,分别对应不同用途的页面:

  1. Welcome:服务首页(根路径)
  2. Login:登录、双因素认证(OTP)、授权确认、注册、找回密码等页面
  3. Account:用户账户管理页面
  4. Admin Console:管理员控制台
  5. Email:系统自动发送邮件的模板

其中,后四种可以在管理控制台中为每个 Realm 单独设置。只要在 themes 目录下新建对应文件夹,重启服务器后就能在控制台中选择。

以我们的示例为例,使用账号 initial1 / zaq1!QAZ 登录管理后台,进入对应 Realm 的 Themes 设置页:

keycloak themes

可以看到,主题是按 Realm 隔离的,不同 Realm 可使用不同主题。图中我们为 SpringBootKeycloak 这个 Realm 设置了 custom 主题用于账户管理。

2.3. 主题结构解析

一个完整的主题除了 HTML 模板、资源文件(图片、CSS)、国际化资源外,还包括两个关键部分:主题属性文件脚本支持

每个主题类型下都有一个 theme.properties 文件,定义了继承关系、资源引用等。例如 account 类型的配置:

parent=base
import=common/keycloak

styles=css/account.css
stylesCommon=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css

解释一下:

  • parent=base:继承 base 主题的模板和资源
  • import=common/keycloak:引入公共样式资源
  • styles:声明本主题独有的 CSS 文件
  • stylesCommon:引入通用样式(如 PatternFly UI 框架)

如果需要添加 JS 脚本(比如表单验证、动态交互),可以:

  1. 在主题目录下创建 resources/js/ 文件夹
  2. 放入 JS 文件(如 script1.js
  3. theme.properties 中声明:
scripts=js/script1.js js/script2.js

Keycloak 会在渲染页面时自动加载这些脚本。

2.4. 实战:定制账户管理页面

来点实际的!我们以 账户管理页面 为例,演示如何更换 Logo。

原始页面长这样(访问 http://localhost:8080/realms/master/account/#/personal-info):

keycloak account before

步骤一:创建主题目录

themes/custom/ 下新建 account 文件夹。建议直接从 theme/keycloak/accountkeycloak.v2/account 复制一份,避免遗漏依赖。

  1. 将新 Logo(如 baeldung.png)放入 themes/custom/account/resources/public/
  2. 修改 themes/custom/account/theme.properties,添加:
# 页面左上角的 Logo,必须是相对路径
logo=/public/baeldung.png

刷新页面,效果立现:

keycloak account after

开发技巧:热加载

开发时频繁重启太麻烦?用以下命令启动 Keycloak,开启热加载:

bin/kc.sh start --spi-theme-static-max-age=-1 --spi-theme-cache-themes=false --spi-theme-cache-templates=false

这样修改 CSS、HTML、图片后无需重启即可生效,效率翻倍 ✅

💡 其他类型主题(如 login、admin)的定制方式完全相同:新建对应目录,放入资源,修改 theme.properties

2.5. 定制欢迎页(Welcome Page)

欢迎页是用户访问 Keycloak 根路径(如 http://localhost:8080)时看到的首页。

步骤一:创建 welcome 主题

  1. themes/custom/ 下新建 welcome 目录
  2. theme/keycloak/welcome 复制 index.ftltheme.propertiesresources 资源

步骤二:启动时指定欢迎主题

必须通过启动参数显式指定,否则不生效:

bin/kc.sh start-dev --spi-theme-welcome-theme=custom

步骤三:修改背景图

原始页面:

WelcomeBefore

操作:

  1. 将新背景图 geo.png 放入 themes/custom/welcome/resources/
  2. 修改 resources/css/welcome.css
body {
    background: #fff url(../geo.png);
    background-size: cover;
}

效果:

WelcomeAfter


3. 嵌入式 Keycloak 服务器的主题定制

嵌入式 Keycloak 场景中,Keycloak 作为 Spring Boot 应用的一部分运行,没有独立安装包。因此,所有主题资源必须放在项目源码中

推荐路径:src/main/resources/themes

主题结构和定制方式与独立服务器完全一致,但需额外配置让 Keycloak 找到这些资源。

3.1. 在 Realm 配置中指定主题

以账户管理主题为例。独立部署时我们在控制台设置,嵌入式则需修改 Realm 配置文件(如 baeldung-realm.json):

"accountTheme": "custom",

其他类型(如 login、email)若未指定,则使用默认主题。

3.2. 指定主题目录位置

告诉 Keycloak 去哪里加载 custom 主题,有三种方式:

方式一:启动参数(推荐)

mvn spring-boot:run -Dkeycloak.theme.dir=src/main/resources/themes

方式二:代码中设置系统属性

@SpringBootApplication 主类中:

public static void main(String[] args) {
    System.setProperty("keycloak.theme.dir", "src/main/resources/themes");
    SpringApplication.run(JWTAuthorizationServerApp.class, args);
}

方式三:修改 keycloak-server.json

在服务器配置中指定:

"theme": {
    "welcomeTheme": "custom",
    "folder": {
        "dir": "src/main/resources/themes"
    }
}

⚠️ 注意:welcomeTheme 属性必须显式设置才能启用自定义欢迎页。

其余所有操作(改 CSS、换图片)与独立部署完全相同。

访问地址

  • 欢迎页:http://localhost:8083/auth
  • 账户管理页:http://localhost:8083/auth/realms/baeldung/account
  • 登录账号:user@example.com / 123

4. 总结

本文系统讲解了 Keycloak 主题的:

  • ✅ 五种类型及其用途
  • ✅ 主题继承机制与 theme.properties 配置
  • ✅ 独立部署与嵌入式场景下的定制方法
  • ✅ 开发期热加载技巧,避免反复重启

核心思想就一句话:不要改内置主题,新建继承主题才是正道

所有示例代码已上传 GitHub:


原始标题:Customizing Themes for Keycloak