自定义 Keycloak 主题
1、概览
Keycloak 是一个开源的身份和访问管理(Identity and Access Management,IAM)解决方案,可以作为第三方授权服务器来管理 Web 或移动应用的身份验证和授权。
本文将带你了解如何自定义 Keycloak 的主题,为终端用户的网页提供不同的外观。
本文以之前的文章为基础:《Keycloak 指南》和《在 Spring Boot 中嵌入 Keycloak》。因此,对于初学者来说,最好先阅读这两篇文章。
2、Keycloak 的主题
2.1、默认主题
Keycloak 中预置了几个主题,并与发行版绑定在一起。
对于单机版服务器,可在 ../lib/lib/main/org.keycloak.keycloak-themes-20.0.3.jar
(可使用任何标准 ZIP 压缩工具打开)的主题目录下的不同文件夹中找到这些主题:
base
:包含 HTML 模板和 Message Bundle 的骨架主题;所有主题(包括自定义主题)一般都继承自 base 主题keycloak
:包含用于美化页面的图片和样式表;如果我们不提供自定义主题,则默认使用该主题keycloak.v2
:基于 React 的主题;新管理控制台的一部分;旧控制台已过时,将在 Keycloak 21 中移除。
不建议修改现有主题。相反,应该创建一个新主题,从上述两个主题中继承。
要创建一个新的自定义主题,需要在 themes 目录中添加一个新的文件夹,称之为 custom。如果想要完全重建,则建议从 base 文件夹中复制内容。
在本例中,我们并不打算替换所有内容,因此从 keycloak 目录中获取内容。
2.2、主题类型
Keycloak 支持五种主题:
- Welcome:用于欢迎页
- Login:用于登录、OTP、授予、注册和忘记密码页面
- Account:用于用户账户管理页面
- Admin Console:用于管理控制台
- Email:用于服务器发送的电子邮件
上述列表中的最后四个主题可以通过独立服务器的管理控制台进行设置。当我们在 themes 目录下创建一个新文件夹后,服务器重启后就可以选择该文件夹。
使用凭证 initial1
/ zaq1!QAZ
(在 上一文章 中设置的)登录管理控制台,并转到 Realm 的 “Themes” 选项卡:
注意,主题是按 Realm 设置的,因此可以为不同的 Realm 设置不同的主题。在这里,我们为 SpringBootKeycloak Realm (也是在 上文 中创建的)的用户账户管理设置自定义主题。
2.3、主题的结构
除了 “默认主题” 部分概述的 HTML 模板、Message Bundle、图片和样式表外,Keycloak 中的主题还包括其他一些元素 - 主题属性和脚本。
每个主题类型都包含一个 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
如你所见,该主题从 base 主题中扩展,以获得所有 HTML 和 Message Bundle,同时还导入了 common 主题,以包含其中的一些样式。除此之外,它还定义了自己的样式 css/account.css
。
脚本是一项可选功能。如果需要在特定主题类型的模板中包含量身定制的 JavaScript 文件,可以创建一个 resources/js
目录并将它们保存在其中。接下来,需要在 theme.properties
中包含它们:
scripts=js/script1.js js/script2.js
2.4、添加自定义内容
以账户管理页面为例,看看如何更改其外观。准确地说,更改页面上的 Logo。
在进行所有更改之前,可从先访问 http://localhost:8080/realms/master/account/#/personal-info
查看原始模板:
接下来,尝试将 Logo 更改为自己的 Logo。为此,需要在 themes/custom 目录下添加一个新文件夹。可以从 theme/keycloak.v2 目录中复制,这样就能获得所有需要的元素。
现在,只需将新 Logo 文件(如 baeldung.png 文件)添加到 custom/account 目录下的 resources/public 文件中,并修改 account 文件夹下的 theme.properties
文件即可:
# 这是左上角的 Logo。
# 必须是相对路径。
logo=/public/baeldung.png
页面现在的样子如下:
在开发阶段,如果希望立即看到更改的效果,而无需重启服务器。可以使用以下命令运行 Keycloak:
bin/kc.[sh|bat] start --spi-theme-static-max-age=-1 --spi-theme-cache-themes=false --spi-theme-cache-templates=false
与这里自定义 account 主题的方法类似,要更改其他主题类型的外观,需要添加名为 admin、email 或 login 的新文件夹,并遵循相同的流程。
2.5、自定义欢迎页面
要自定义欢迎页面,首先要在 themes/custom 下创建 welcome 文件夹。同样,为了谨慎起见,应将 index.ftl 和 theme.properties 以及现有资源从 theme/keycloak/welcome 目录中复制出来。
其次,必须使用以下命令运行 Keycloak:
bin/kc.[sh|bat] start-dev --spi-theme-welcome-theme=custom
现在,尝试更改该页面的背景。
访问 http://localhost:8080
,看看它最初的样子:
要更改背景图片,先把新的背景图(如 geo.png
)保存在 themes/custom/welcome/resources 中,然后编辑 resources/css/welcome.css
:
body {
background: #fff url(../geo.png);
background-size: cover;
}
效果如下:
3、嵌入式 Keycloak 服务器
嵌入式 Keycloak 服务器 意味着我们的机器上没有安装 IAM Provider。因此,我们需要将所有必需的文件,例如 themes.properties 和 CSS 文件,保留在我们的源代码中。
可以将它们放在 Spring Boot 项目的 src/main/resources/themes 文件夹中。
当然,由于主题结构的文件是相同的,对其进行自定义的方式也与独立服务器相同。
不过,需要配置一些东西,以指示 Keycloak 服务器从自定义主题中获取内容。
3.1、更改 Realm 定义文件
首先,来看看如何为给定的主题类型指定自定义主题。
回想一下,在独立服务器的情况下,我们在管理控制台的 Themes 页面上,从 Account Theme 的下拉菜单中添加了 custom 主题。
为了达到同样的效果,需要在 realm 定义文件 baeldung-realm.json
中添加一行内容:
"accountTheme": "custom",
这样就行了,所有其他类型(如 Login 和 Email)仍将遵循标准主题。
3.2、重定向到 custom 主题目录
接下来,来看看如何告诉服务器上述自定义主题的位置。
可以通过几种方式来实现这一目标。
在启动嵌入式服务器时,可以将主题目录指定为 VM 参数:
mvn spring-boot:run -Dkeycloak.theme.dir=/src/main/resources/themes
也可以通过编程式实现同样的目的,在 @SpringBootApplication
类中将其设置为系统属性:
public static void main(String[] args) throws Exception {
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
,我们可以使用 john@test.com/123
凭证访问该页面。
4、总结
本文先介绍了 Keycloak 中预置的几个主题,及其它们的结构。然后介绍了如何通过继承来自定义 Keycloak 主题,包括在嵌入式 Keycloak 服务器中实现同样的功能。
Ref:https://www.baeldung.com/spring-keycloak-custom-themes