1. 概述

Keycloak 是一个功能强大的开源身份和访问管理工具,常被用作 Web 或移动应用的第三方认证服务器。除了管理员手动创建用户外,Keycloak 还支持用户自助注册(Self-Registration),提升用户体验。

更进一步,除了默认的姓名、邮箱等字段,我们还可以在注册页面添加自定义字段,满足业务需求。

本文将重点介绍:

✅ 如何开启 Keycloak 的用户自助注册功能
✅ 如何在注册页面添加自定义字段(如出生日期)
✅ 分别针对独立部署和嵌入式部署的实现方式

⚠️ 本文基于之前关于 自定义登录页面 的配置,建议先完成相关基础设置。


2. 独立部署的 Keycloak 服务

我们先从最常见的独立运行的 Keycloak 服务器入手。

2.1 开启用户自助注册

要启用自助注册,首先启动 Keycloak 服务:

kc.bat start-dev

启动后访问管理后台:http://localhost:8080/admin,使用初始账号密码登录(例如:admin / admin123)。

进入 Realm Settings → Login 页面,找到 User registration 选项并开启:

user registration

✅ 保存后,注册功能即刻生效。

此时再访问应用的登录页(例如): http://localhost:8080/realms/SpringBootKeycloak/protocol/openid-connect/auth?response_type=code&client_id=login-app&scope=openid&redirect_uri=http://localhost:8081/

会看到多出一个 Register 链接:

login with register link

点击进入注册页面,默认包含姓名、邮箱等基础字段:

registration page

💡 注意:页面样式与默认 Keycloak 不同,因为我们继承了之前自定义的主题。


2.2 添加自定义用户属性

接下来我们想在注册表单中加入“出生日期”(Date of Birth)字段。

步骤一:复制模板文件

假设你已经配置了自定义主题,路径为 themes/custom/
将 Keycloak 默认模板中的注册页复制到你的主题目录:

cp themes/base/login/register.ftl themes/custom/login/register.ftl

步骤二:修改 register.ftl

<form> 中添加如下 HTML 片段:

<div class="form-group">
    <div class="${properties.kcLabelWrapperClass!}">
        <label for="user.attributes.dob" class="${properties.kcLabelClass!}">
          Date of birth</label>
    </div>

    <div class="${properties.kcInputWrapperClass!}">
        <input type="date" class="${properties.kcInputClass!}" 
          id="user.attributes.dob" name="user.attributes.dob" 
          value="${(register.formData['user.attributes.dob']!'')}"/>
    </div>
</div>

✅ 注意命名规范:name="user.attributes.dob" 是 Keycloak 的约定格式,会自动映射为用户属性。

步骤三:验证效果

重新加载页面,注册新用户时将看到新增的日期选择框:

jane doe

注册完成后,进入管理后台 → Users → 查找该用户 → Attributes 标签页,确认 dob 属性已正确保存:

jane doe

✅ 成功!字段数据已持久化。


3. 嵌入式 Keycloak 服务(集成在 Spring Boot 中)

很多场景下,我们会把 Keycloak 嵌入到 Spring Boot 应用中进行本地测试或快速开发。

实现方式大同小异,但配置方式略有不同。

3.1 启用注册功能

在嵌入式模式中,Realm 配置通常通过 JSON 文件定义。我们需要在 baeldung-realm.json 中开启注册权限:

"registrationAllowed": true,

示例路径:src/main/resources/baeldung-realm.json

否则即使前端有注册入口,提交时也会被拦截。

3.2 添加自定义字段

和独立部署一样,我们仍需修改 register.ftl 模板文件,加入 dob 字段:

<div class="form-group">
    <div class="${properties.kcLabelWrapperClass!}">
        <label for="user.attributes.dob" class="${properties.kcLabelClass!}">
          Date of birth</label>
    </div>

    <div class="${properties.kcInputWrapperClass!}">
        <input type="date" class="${properties.kcInputClass!}" 
          id="user.attributes.dob" name="user.attributes.dob" 
          value="${(register.formData['user.attributes.dob']!'')}"/>
    </div>
</div>

然后将该文件放入项目资源目录:

src/main/resources/themes/custom/login/register.ftl

确保 Spring Boot 启动时能正确加载自定义主题。

3.3 效果预览

启动应用后访问登录页:

http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/auth?response_type=code&&scope=openid%20write%20read&client_id=newClient&redirect_uri=http://localhost:8089/

可以看到注册页面已包含“Date of birth”字段:

Embedded register

3.4 注意事项 ⚠️

  • 嵌入式模式下的用户是临时的:通过注册接口创建的用户不会写入配置文件。
  • 服务重启后用户丢失,仅适用于开发调试阶段。
  • 若需持久化,应配合数据库(如 PostgreSQL)或导出用户数据。

但在开发阶段,这种方式非常方便,可以快速验证 UI 和流程逻辑。


4. 总结

本文实战演示了如何在 Keycloak 中实现用户自助注册,并扩展自定义字段。

核心要点回顾:

场景 关键步骤
独立部署 控制台开启 User registration + 自定义 register.ftl
嵌入式部署 JSON 配置 "registrationAllowed": true + 主题文件注入
自定义字段 使用 user.attributes.xxx 命名规则,确保前后端一致

✅ 推荐做法:

  • 所有 UI 定制均通过 自定义主题 实现
  • 字段命名避免空格和特殊字符,推荐小写 + 下划线
  • 开发阶段用嵌入式快速迭代,生产环境务必使用独立部署 + 持久化存储

💡 源码参考:

踩坑提醒:别忘了清浏览器缓存或使用无痕模式测试,否则可能看不到模板更新!


原始标题:Keycloak User Self-Registration | Baeldung