升级 Keycloak

本指南介绍如何升级 Keycloak。按以下顺序使用以下步骤

  1. 查看 Keycloak 上一个版本的迁移更改。

  2. 升级 Keycloak 服务器。

  3. 升级 Keycloak 适配器。

  4. 升级 Keycloak 管理客户端。

迁移更改

迁移到 26.0.0

Infinispan 序列化更改

序列化是将 Java 对象转换为字节以在 Keycloak 服务器之间通过网络发送它们的流程。在 Keycloak 26 中,序列化库已从 JBoss Marshalling 更改为 Infinispan Protostream。这些库彼此之间不兼容,因此需要采取一些步骤来确保不会丢失会话数据。

JBoss Marshalling 和 Infinispan Protostream 彼此之间不兼容,错误使用可能会导致数据丢失。因此,升级到此版本时,所有缓存都将被清除。

为了防止丢失用户会话,请先升级到 Keycloak 25,然后按照 Keycloak 25 迁移指南中的说明启用持久会话功能。

运算符不再默认设置为 proxy=passthrough

运算符将不再默认设置为主机名 v1 设置 proxy=passthrough。这允许使用主机名 v2 为固定边缘主机名进行部署,以便在没有其他选项的情况下按预期工作。

ClusterProvider API 中的新方法

以下方法已添加到 org.keycloak.cluster.ClusterProvider

  • void notify(String taskKey, Collection<? extends ClusterEvent> events, boolean ignoreSender, DCNotify dcNotify)

当多个事件发送到同一个 taskKey 时,此方法会将事件批处理,并且只执行一次网络调用。这是一种优化方法,可以减少流量和与网络相关的资源。

在 Keycloak 26 中,新方法具有默认实现,以保持与自定义实现的向后兼容性。默认实现对每个事件执行一次网络调用,它将在 Keycloak 的未来版本中删除。

为了提高组的可扩展性,现在在删除领域时直接从数据库中删除组。因此,当删除领域时,与组相关的事件(例如 GroupRemovedEvent)不再被触发。

如果您有扩展程序在删除领域时处理任何与组相关的事件,请确保使用 RealmRemovedEvent 而不是 GroupRemovedEvent 来执行任何清理或自定义处理,以便在删除领域及其组时执行任何清理或自定义处理。

GroupProvider 接口也更新了新的 preRemove(RealmModel) 方法,以强制实现正确处理删除领域时删除组。

从根目录到相对路径的自动重定向

当指定 http-relative-path 属性时,用户将自动重定向到 Keycloak 托管的路径。这意味着当相对路径设置为 /auth 且用户访问 localhost:8080/ 时,该页面将重定向到 localhost:8080/auth

当指定 http-management-relative-pathhttp-relative-path 属性时,管理界面也是如此。

它改善了用户体验,因为用户不再需要显式地将相对路径设置为 URL。

运算符调度默认值

Keycloak Pod 现在将具有默认亲和力,以防止来自同一 CR 的多个实例部署在同一节点上,并且来自同一 CR 的所有 Pod 都会优先在同一区域内,以防止拉伸缓存集群。

运算符的默认 CPU 和内存限制/请求

为了遵循最佳实践,引入了运算符的默认 CPU 和内存限制/请求。它会影响非 OLM 和 OLM 安装。要覆盖 OLM 安装的默认值,请编辑运算符的 订阅 中的 resources 部分。

keycloak-common 模块中的弃用

以下项目已弃用,将在即将发布的 Keycloak 版本中删除,没有替代品

  • org.keycloak.common.util.reflections.Reflections.newInstance(java.lang.Class<T>)

  • org.keycloak.common.util.reflections.Reflections.newInstance(java.lang.Class<?>, java.lang.String)

  • org.keycloak.common.util.reflections.SetAccessiblePrivilegedAction

  • org.keycloak.common.util.reflections.UnSetAccessiblePrivilegedAction

一致使用 UTF-8 字符集进行 URL 编码

org.keycloak.common.util.Encode 现在始终使用 UTF-8 字符集进行 URL 编码,而不是隐式依赖于 file.encoding 系统属性。

配置 LDAP 连接池

在此版本中,LDAP 连接池配置完全依赖于系统属性。主要原因是 LDAP 连接池配置是 JVM 级别的配置,而不是特定于单个领域或 LDAP 提供者实例。

与之前的版本相比,任何与 LDAP 连接池相关的领域配置都将被忽略。如果您要从之前的版本迁移,其中在 LDAP 提供者中设置了以下任何设置,请考虑使用系统属性代替

  • connectionPoolingAuthentication

  • connectionPoolingInitSize

  • connectionPoolingMaxSize

  • connectionPoolingPrefSize

  • connectionPoolingTimeout

  • connectionPoolingProtocol

  • connectionPoolingDebug

有关更多详细信息,请参阅 配置连接池

此版本引入了轻松地为 base/loginkeycloak.v2/login 主题的登录页面添加自定义页脚的功能。要使用自定义页脚,请在您的自定义登录主题中创建一个包含所需内容的 footer.ftl 文件。

有关更多详细信息,请参阅 向登录主题添加自定义页脚

在重启期间持久化已吊销的访问令牌

在本版本中,使用嵌入式缓存时,默认情况下,已撤销的访问令牌将写入数据库并在集群重新启动时重新加载。

要禁用此行为,请使用 SPI 选项 spi-single-use-object-infinispan-persist-revoked-tokens,如 所有提供程序配置 指南中所述。

SingleUseObjectProvider 的 SPI 行为已更改,对于已撤销的令牌,仅 putcontains 方法必须使用。此行为默认情况下强制执行,可以使用 SPI 选项 spi-single-use-object-infinispan-persist-revoked-tokens 禁用。

高可用性多站点部署

Keycloak 26 引入了对推荐的 HA 多站点架构的重大改进,最显著的是

  • Keycloak 部署现在能够同时处理两个站点中的用户请求。以前仅在一次处理一个站点的请求的负载均衡器配置将继续有效。

  • 现在需要对站点之间的连接进行主动监控,以在出现故障时进行站点之间的复制。蓝图描述了使用 Alertmanager 和 AWS Lambda 的设置。

  • 负载均衡器蓝图已更新为使用 AWS 全局加速器,因为这避免了由于客户端的 DNS 缓存导致的长时间故障转移时间。

  • 持久性用户会话现在是架构的要求。因此,用户会话将在 Keycloak 或 Infinispan 升级期间保留。

  • 外部 Infinispan 请求处理已得到改进,以减少内存使用量和请求延迟。

由于上述更改,您现有的 Keycloak 部署需要进行以下更改。

  1. 当启用 multi-site 功能时,缓存配置文件提供的 distributed-cache 定义将被忽略,因此您必须使用 cache-remote-* 命令行参数或 Keycloak CR 配置与外部 Infinispan 部署的连接,如蓝图中所述。所有 remote-store 配置必须从缓存配置文件中删除。

  2. 检查您在外部 Infinispan 中当前的缓存配置,并使用 Keycloak 文档最新版本中概述的配置更新它们。虽然以前版本的缓存配置在站点之间的备份复制失败时仅记录警告,但新配置确保了两个站点中的状态保持同步:当两个站点之间的传输失败时,调用者将看到错误。因此,您需要设置监控,以在站点故障时断开两个站点之间的连接。Keycloak 高可用性指南包含有关如何设置此功能的蓝图。

  3. 虽然以前的负载均衡器配置将继续与 Keycloak 兼容,但请考虑将现有 Route53 配置升级,以避免由于客户端侧 DNS 缓存导致的长时间故障转移时间。

  4. 如果您使用远程存储配置更新了缓存配置 XML 文件,则它们将不再起作用。相反,请启用 multi-site 功能并使用 cache-remove-* 选项。

单站点设置中的外部 Infinispan

如果您在单站点设置中使用外部 Infinispan,则在早期的 Keycloak 版本中不支持此功能,并且在 Keycloak 26 中也不支持。为了防止用户通过 Keycloak 的缓存 XML 中的手动配置或通过 CLI 选项意外使用它,现在使用功能标志 cache-embedded-remote-store 对其进行保护。它被标记为实验性,因此不支持。Keycloak 26 将不会启动此类配置,而是会显示错误,除非启用此实验性功能。

如果您一直在使用外部 Infinispan 来使用户在重启和升级之间保持登录状态,请使用 persistent-user-sessions 功能,该功能默认情况下处于启用状态。然后,外部 Infinispan 将不再需要。

实验性功能 cache-embedded-remote-store 将在未来的次要版本中删除

管理员引导和恢复

以前,当所有管理员用户都被锁定时,很难重新获得对 Keycloak 实例的访问权限。该过程需要多个高级步骤,包括直接访问数据库和手动更改。为了改善用户体验,Keycloak 现在提供了多种引导新管理员帐户的方法,这些方法可用于从这种情况中恢复。

因此,环境变量 KEYCLOAK_ADMINKEYCLOAK_ADMIN_PASSWORD 已被弃用。您应该改用 KC_BOOTSTRAP_ADMIN_USERNAMEKC_BOOTSTRAP_ADMIN_PASSWORD。这些也是通用选项,因此可以通过 cli 或其他配置源指定它们,例如 --bootstrap-admin-username=admin。有关更多信息,请参阅新的 引导管理员和恢复 指南。

应用程序启动的必备操作重定向现在包含 kc_action 参数

从应用程序启动的必备操作执行重定向回来时,现在通过 kc_action 参数返回必备操作提供程序名称。这简化了对客户端执行了哪个必备操作的检测。执行的结果可以通过 kc_action_status 参数确定。

注意:此功能需要对 Keycloak JS 适配器进行更改,因此建议您升级到适配器的最新版本,如果您想使用此功能。

keycloak-services 模块中的弃用

UserSessionCrossDCManager 已被弃用,并计划在 Keycloak 的未来版本中删除。阅读 UserSessionCrossDCManager Javadoc 以了解要使用的替代方法。

身份提供程序不再可从 realm 表示中获得

作为对 realm 和组织在具有许多身份提供程序时的可扩展性改进的一部分,realm 表示不再包含身份提供程序列表。但是,在导出 realm 时,它们仍然可从 realm 表示中获得。

要查询 realm 中的身份提供程序,最好使用 /realms/{realm}/identity-provider/instances 端点。此端点支持过滤器和分页。

CLI 导入占位符替换

CLI 命令 kc.[sh|bat] import 现在启用了占位符替换。以前,占位符替换仅在启动时为 realm 导入启用。

如果您希望为 import 命令禁用占位符替换,请添加系统属性 -Dkeycloak.migration.replace-placeholders=false

按名称搜索 realm 的新 Java API

RealmProvider Java API 现在包含一个新方法 Stream<RealmModel> getRealmsStream(String search),它允许按名称搜索 realm。虽然有一个默认实现,它在从提供程序加载流之后过滤流,但鼓励实现提供更有效的实现。

密钥库和信任库默认格式更改

Keycloak 现在根据文件扩展名确定密钥库和信任库的格式。如果文件扩展名是 .p12.pkcs12.pfx,则格式为 PKCS12。如果文件扩展名是 .jks.keystore.truststore,则格式为 JKS。如果文件扩展名是 .pem.crt.key,则格式为 PEM。

您仍然可以通过显式指定 https-key-store-typehttps-trust-store-type 来覆盖自动检测。管理界面及其 https-management-key-store-type 也是如此。FIPS 严格模式的限制保持不变。

spi-truststore-file-* 选项和与信任库相关的选项 https-trust-store-* 已被弃用,我们强烈建议使用系统信任库。有关更多详细信息,请参阅相关的 指南

提高身份提供程序选择性能

IDENTITY_PROVIDER 表中添加了新索引,以提高获取与组织关联的 IDP 以及获取可用于登录的 IDP(已启用、不是仅链接、未标记为隐藏在登录页面上的 IDP)的查询性能。

如果表当前包含超过 300.000 个条目,Keycloak 将默认情况下在自动模式迁移期间跳过索引的创建,而是在迁移期间将 SQL 语句记录到控制台中。在这种情况下,必须在 Keycloak 启动后手动在数据库中运行这些语句。

此外,kc.orghideOnLoginPage 配置属性已迁移到身份提供程序本身,以允许在搜索提供程序时进行更有效的查询。因此,API 客户端应在 IdentityProviderRepresentation 中使用 getOrganizationId/setOrganizationIdisHideOnLogin/setHideOnLogin 方法,并避免使用现在已弃用的旧配置属性设置这些属性。

删除 GELF 日志处理程序

GELF 支持已有一段时间被弃用了,在此版本中,它最终已从 Keycloak 中删除。其他日志处理程序可用,并且完全支持用作 GELF 的替代品,例如 Syslog。有关详细信息,请参阅 日志记录指南

common 主题资源的路径已更改

keycloak 主题的 common 资源中的一些路径已更改,特别是第三方库的资源。确保相应地更新您的自定义主题

  • node_modules/patternfly/dist 现在为 vendor/patternfly-v3

  • node_modules/@patternfly/patternfly 现在为 vendor/patternfly-v4

  • node_modules/@patternfly-v5/patternfly 现在为 vendor/patternfly-v5

  • node_modules/rfc4648/lib 现在为 vendor/rfc4648

此外,以下资源已从 common 主题中删除

  • node_modules/alpinejs

  • node_modules/jquery

如果您之前在主题中使用了任何已删除的资源,请确保将它们添加到您自己的主题资源中。

其他数据源现在需要使用 XA

Keycloak 默认情况下不使用 XA 数据源。但是,如果使用多个数据源,则这被认为是不安全的。从本版本开始,如果您向 Keycloak 添加其他数据源,则需要使用 XA 数据源。如果默认数据源支持 XA,您可以通过设置 --transaction-xa-enabled=true 选项来执行此操作。对于其他数据源,您需要在 quarkus.properties 文件中使用 quarkus.datasource.<your-datasource-name>.jdbc.transactions=xa 选项。最多可以有一个数据源是非 XA 数据源。当您没有为事务存储提供持久性存储时,不支持恢复。

主机名 v1 功能已删除

已弃用的主机名 v1 功能已删除。此功能在 Keycloak 25 中被弃用,并由主机名 v2 替换。如果您仍在使用此功能,则必须迁移到主机名 v2。有关更多详细信息,请参阅 配置主机名 (v2)初始迁移指南

代理选项已删除

已弃用的 proxy 选项已删除。此选项在 Keycloak 24 中被弃用,并由 proxy-headers 选项与 hostname 选项结合使用(根据需要)替换。有关更多详细信息,请参阅 使用反向代理初始升级指南

默认情况下,所有用户会话都将持久化

由于数据库现在是用户会话的真实来源,因此可以限制会话缓存的大小以减少内存使用。 如果您使用默认的conf/cache-ispn.xml文件,则用于存储用户和客户端会话的缓存默认情况下配置为仅存储 10000 个会话,每个条目有一个所有者。

使用类似于下面所示的配置更新您的自定义嵌入式 Infinispan 缓存配置文件,用于缓存sessionsclientSessionsofflineSessionsofflineClientSessions

<distributed-cache name="sessions" owners="1">
    <!-- other configuration -->
    <memory max-count="10000"/>
</distributed-cache>

有关更多详细信息,请参阅配置分布式缓存指南。

启用持久会话时删除空闲会话的宽限期

以前版本的 Keycloak 在用户和客户端会话的空闲时间添加了 2 分钟的宽限期。 这是由于以前的体系结构,其中会话刷新时间在集群中异步复制。 使用持久用户会话,这不再必要,因此宽限期现在已删除。

要保留旧的行为,请更新您的 realm 配置并延长会话和客户端空闲时间 2 分钟。

对传统redirect_uri参数和 SPI 选项的支持已删除

以前版本的 Keycloak 支持自动注销用户并通过打开注销端点 URL(例如http(s)://example-host/auth/realms/my-realm-name/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri)重定向到应用程序。 此功能在 Keycloak 18 中已弃用,并且在此版本中已删除,有利于遵循 OpenID Connect 规范。

作为此更改的一部分,SPI 的以下相关配置选项已被删除

  • --spi-login-protocol-openid-connect-legacy-logout-redirect-uri

  • --spi-login-protocol-openid-connect-suppress-logout-confirmation-screen

如果您仍在使用这些选项或redirect_uri参数进行注销,则应改而实现OpenID Connect RP-Initiated Logout 规范

--optimized启动选项的额外验证

--optimized启动选项现在要求首先构建优化的服务器镜像。 这可以通过首先运行kc.sh|bat build或通过任何其他服务器命令(如startexportimport)来实现,而不带--optimized标志。

适配器和杂项 BOM 文件已删除

org.keycloak.bom:keycloak-adapter-bomorg.keycloak.bom:keycloak-misc-bom BOM 文件已删除。 适配器 BOM 已经没有用处,因为大多数 Java 适配器都已删除。 杂项 BOM 仅包含一个工件keycloak-test-helper,该工件也将在本版本中删除。

keycloak-test-helper 已删除

maven 工件org.keycloak:keycloak-test-helper在本版本中已删除。 该工件提供了一些用于处理 Java 管理客户端的帮助方法。 如果您使用帮助方法,则可以根据需要将它们分叉到您的应用程序中。

JEE 管理客户端已删除

JEE 管理客户端在本版本中已删除。 我们仍然支持 Jakarta 管理客户端。

用于凭据的新通用事件类型

现在有用于更新(UPDATE_CREDENTIAL)和删除(REMOVE_CREDENTIAL)凭据的通用事件。 凭据类型在事件的credential_type属性中描述。 新的事件类型受电子邮件事件侦听器支持。

以下事件类型现已弃用,并将将在未来版本中删除:UPDATE_PASSWORDUPDATE_PASSWORD_ERRORUPDATE_TOTPUPDATE_TOTP_ERRORREMOVE_TOTPREMOVE_TOTP_ERROR

--import-realm选项可以导入主 realm

在运行带有--import-realm选项的startstart-dev命令之前,如果主 realm 不存在,则如果它存在于导入材料中,它将被导入。 以前的行为是先创建主 realm,然后跳过其导入。

BouncyCastle FIPS 已更新

我们现在使用 BouncyCastle FIPS 库的版本 2 测试并支持我们的 FIPS 140-2 集成。 此版本已通过 Java 21 认证。 如果您使用 FIPS 140-2 集成,建议您将 BouncyCastle FIPS 库升级到最新文档中提到的版本。

BouncyCastle FIPS 版本 2 已通过 FIPS 140-3 认证。 因此,只要在符合 FIPS 140-3 的系统上使用 Keycloak,它就可以符合 FIPS 140-3。 这可能是基于 RHEL 9 的系统,它本身符合 FIPS 140-3。 但请注意,基于 RHEL 8 的系统仅通过 FIPS 140-2 认证。

setOrCreateChild()方法已从 JavaScript 管理客户端中删除

groups.setOrCreateChild()方法已从基于 JavaScript 的管理客户端中删除。 如果您仍在使用此方法,请改用createChildGroup()updateChildGroup()方法。

Keycloak JS

此版本包含对 Keycloak JS 库的几个更改,应予以考虑。 这些更改的主要动机是将库与 Keycloak 服务器分离,以便可以独立地重构它,简化代码并使其在将来更容易维护。 更改如下

库不再从服务器静态提供

Keycloak JS 库不再从 Keycloak 服务器静态提供。 这意味着以下 URL 不再可用

  • /js/keycloak-authz.js

  • /js/keycloak-authz.min.js

  • /js/keycloak.js

  • /js/keycloak.min.js

  • /js/{version}/keycloak-authz.js

  • /js/{version}/keycloak-authz.min.js

  • /js/{version}/keycloak.js

  • /js/{version}/keycloak.min.js

此外,与这些 URL 上的库链接的keycloakJsUrl属性已从管理控制台主题中删除。 如果您的自定义主题使用此属性来包含库,则应更新您的主题以使用其他方法包含库。

如果您还没有,则应使用包管理器(如NPM)在您的项目中包含库。 该库在 NPM 注册表中以keycloak-js的形式提供。 您可以使用以下命令安装它

npm install keycloak-js

或者,服务器的发布包含一个keycloak-js-26.0.0.tgz存档中的库副本。 您可以从那里将库复制到您的项目中。 如果您直接在浏览器中使用库而没有构建,则需要自己托管该库。 包管理器仍然是将库包含在项目中的推荐方法,因为它将在将来更容易更新库。

对 UMD 发行版的支持已删除

Keycloak JS 库的 UMD 发行版通用模块定义已删除。 这意味着该库不再作为全局变量公开,而是必须作为模块导入。 此更改符合现代 JavaScript 开发实践,并允许在浏览器和构建工具之间提供更一致的体验,通常会导致更可预测的代码,副作用更少。

如果您使用的是像 Vite 或 Webpack 这样的捆绑器,则不会有任何变化,您将与以前一样体验。 如果您直接在浏览器中使用库,则需要更新您的代码以将库作为模块导入

<!-- Before -->
<script src="/path/to/keycloak.js"></script>
<script>
    const keycloak = new Keycloak();
</script>

<!-- After -->
<script type="module">
    import Keycloak from '/path/to/keycloak.js';
    const keycloak = new Keycloak();
</script>

您也可以选择使用导入映射使库的导入不那么冗长

<script type="importmap">
    {
        "imports": {
            "keycloak-js": "/path/to/keycloak.js"
        }
    }
</script>
<script type="module">
    // The library can now be imported without specifying the full path, providing a similar experience as with a bundler.
    import Keycloak from 'keycloak-js';
    const keycloak = new Keycloak();
</script>

如果您使用的是 TypeScript,您可能需要更新您的tsconfig.json才能解析库

{
    "compilerOptions": {
        "moduleResolution": "Bundler"
    }
}
Keycloak实例的配置现在是必需的

以前可以构建Keycloak实例,而不传递任何配置。 然后将从服务器上的keycloak.json文件自动加载配置,该文件基于包含的keycloak.js脚本的路径。 由于库不再从服务器静态提供,因此此功能已删除。 您现在需要在构建Keycloak实例时显式传递配置

// Before
const keycloak = new Keycloak();

// After
const keycloak = new Keycloak({
    url: "http://keycloak-server",
    realm: "my-realm",
    clientId: "my-app"
});

// Alternatively, you can pass a URL to a `keycloak.json` file.
// Note this is not reccomended as it creates additional network requests, and is prone to change in the future.
const keycloak = new Keycloak('http://keycloak-server/path/to/keycloak.json');
登录方法现在是async

Keycloak JS 现在使用 Web Crypto API 执行各种加密功能。 由于此 API 的异步性质,以下公共方法现在将始终返回Promise

  • login()

  • createLoginUrl()

  • createRegisterUrl()

确保更新您的代码以await这些方法

// Before
keycloak.login();
const loginUrl = keycloak.createLoginUrl();
const registerUrl = keycloak.createRegisterUrl();

// After
await keycloak.login();
const loginUrl = await keycloak.createLoginUrl();
const registerUrl = await keycloak.createRegisterUrl();

确保更新您的代码以await这些方法。

现在需要安全的上下文

Keycloak JS 现在需要安全的上下文才能运行。 这样做的原因是库现在使用 Web Crypto API 执行各种加密功能。 此 API 仅在安全上下文中可用,这些上下文是通过 HTTPS、localhost.localhost域提供的上下文。 如果您在不安全的上下文中使用库,则需要更新您的开发环境以使用安全的上下文。

构建时选项的更严格的启动行为

当提供的构建时选项在启动时与上次优化 Keycloak 构建期间在服务器镜像中持久化的值不同时,Keycloak 现在将无法启动。 以前,在这种情况下会显示警告消息。

功能重命名

使用功能版本,功能account3admin2login2已被重命名。 禁用功能时,无需使用版本,例如,管理控制台现在使用--features-disabled=admin禁用。

要使用特定版本的login,请使用--features=login:v1

迁移到 25.0.3

启用暴力破解时,默认情况下会阻止并发登录请求

如果攻击者以并行方式启动了许多登录尝试,则攻击者对密码的猜测次数可能超过暴力破解保护配置允许的次数。 这是因为暴力破解检查发生在暴力破解保护器锁定用户之前。 为了防止这种竞争情况,暴力破解保护器现在拒绝在同一服务器上另一个登录正在进行时发生的所有登录尝试。

如果由于任何原因,新功能想要被禁用,则有一个启动工厂选项

bin/kc.[sh|bat] start --spi-brute-force-protector-default-brute-force-detector-allow-concurrent-requests=true

迁移到 25.0.2

提高用户同意删除的性能

当客户端范围或整个 realm 被删除时,相关的用户同意也应该被删除。为了提升性能,一个新的索引被添加到 USER_CONSENT_CLIENT_SCOPE 表中。

注意,如果该表包含超过 300,000 条记录,Keycloak 默认会在自动 Schema 迁移过程中跳过索引创建,并将 SQL 语句日志记录到控制台。在 Keycloak 启动后,需要在数据库中手动运行这些语句。有关如何配置不同限制的详细信息,请查看 升级指南

迁移到 25.0.0

新的主机名选项

主机名 v2 选项默认受支持,因为旧的主机名选项已弃用,将在后续版本中删除。新的选项默认激活,因此 Keycloak 无法识别旧选项。

必要的迁移列表

旧选项 新选项

hostname <hostname>
hostname-url <url>
hostname-path <path>
hostname-port <port>

hostname <hostname/url>

hostname-admin <hostname>
hostname-admin-url <url>

hostname-admin <url>

hostname-strict-backchannel <true/false>

hostname-backchannel-dynamic <true/false>

如您所见,hostnamehostname-admin 选项的 *-url 后缀已被删除。选项 hostname 同时接受主机名和 URL,但 hostname-admin 现在只接受完整的 URL。

此外,无法单独设置 pathport。您可以通过为 hostnamehostname-admin 选项提供完整的 URL 来实现这一点。

如果端口不是 URL 的一部分,它将从传入的请求标头动态解析。

除非它是 hostnamehostname-admin URL 的一部分,否则不再强制使用 HTTPS。如果没有指定,使用的协议(http/https)将从传入的请求动态解析。hostname-strict-https 选项已被删除。

已删除的选项

hostname-url

hostname-admin-url

hostname-path

hostname-port

hostname-strict-backchannel

hostname-strict-https

为了使用旧的主机名选项以便有更多时间进行迁移,请启用功能 hostname:v1,例如 features=hostname:v1。请注意,只能启用 hostname:v1hostname:v2,不能同时启用两者。
示例
简化表示法
# Hostname v1
bin/kc.[sh|bat] start --hostname=mykeycloak.org --https-port=8543 --hostname-path=/auth --hostname-strict-https=true

# Hostname v2
bin/kc.[sh|bat] start --hostname=https://mykeycloak.org:8543/auth

如您在示例中所见,现在可以使用单个 hostname 选项指定 URL 的所有部分,这简化了主机名设置过程。请注意,HTTPS 不是由 hostname-strict-https 选项强制执行的,而是由在主机名 URL 中指定它来强制执行的。

后端设置
# Hostname v1
bin/kc.[sh|bat] start --hostname=mykeycloak.org --hostname-strict-backchannel=true

# Hostname v2
bin/kc.[sh|bat] start --hostname=mykeycloak.org --hostname-backchannel-dynamic=false

请注意,如果要对后端和前端端点使用相同的 URL,则行为会有所改变。以前,在主机名 v1 中,后端 URL 是从请求标头动态解析的。因此,为了实现所需的结果,您必须指定 hostname-strict-backchannel=true

对于主机名 v2,后端 URL 与前端 URL 相同。为了从请求标头动态解析它,您需要设置 hostname-backchannel-dynamic=true 并为 hostname 选项提供完整的 URL。

有关更多详细信息和更全面的场景,请查看 配置主机名 (v2)

security-admin-console 客户端重定向 URI

${authAdminUrl} 的处理方式已在主机名 v1 中更改。以前使用主机名 v1 时,如果未设置 hostname-adminhostname-admin-url 选项,则管理员 URL 将从请求中动态解析。使用主机名 v2 时,管理员 URL 将默认为前端 URL。如果设置了 hostname 选项并且 hostname-strict 为真,则此更改将阻止使用 Root URL ${authAdminUrl} 的客户端使用具有备用主机名的重定向 URI。您应该考虑使用 hostname-admin 选项而不是重定向 URI 来允许单个备用主机名。应删除备用主机名重定向,因为 security-admin-console 客户端只需要使用 Root URL ${authAdminUrl} 的默认重定向 URI /admin/master/console/*

持久用户会话

以前版本的 Keycloak 仅将离线用户和离线客户端会话存储在数据库中。新功能 persistent-user-sessions 将在线用户会话和在线客户端会话不仅存储在内存中,还存储在数据库中。这将允许用户即使在所有 Keycloak 实例重新启动或升级后也能保持登录状态。

启用持久用户会话

此功能是预览功能,默认情况下处于禁用状态。要使用它,请将以下内容添加到您的构建命令中

bin/kc.sh build --features=persistent-user-sessions ...

有关更多详细信息,请查看 启用和禁用功能 指南。尺寸指南 包含一个新段落,描述启用此功能时更新的资源需求。

如果为现有的部署启用了此功能,该部署仅使用嵌入式 Infinispan 来存储会话,则现有的在线用户和客户端会话将不会迁移到数据库。它只会影响新创建的在线用户和在线客户端会话。

启用持久会话后,在线用户会话、离线用户会话、在线客户端会话和离线客户端会话的内存缓存默认情况下每个节点限制为 10000 个条目,这将减少 Keycloak 在大型安装中的总体内存使用量。从内存中逐出的项目将在需要时按需从数据库加载。要设置缓存的不同大小,请编辑 Keycloak 的缓存配置文件,为这些缓存设置 <memory max-count="..."/>。启用此功能后,预计每次登录、注销和刷新令牌请求都会增加数据库利用率。

要在 Keycloak 多站点设置中配置外部 Infinispan 中的缓存大小,请查阅更新的 使用 Infinispan 运算符部署 Infinispan 以实现高可用性 指南。

启用此功能后,选项 spi-user-sessions-infinispan-offline-session-cache-entry-lifespan-overridespi-user-sessions-infinispan-offline-client-session-cache-entry-lifespan-override 将不再可用,因为它们以前用于覆盖离线会话保留在内存中的时间。

在升级期间迁移用户会话

从 Keycloak 24 或更早版本升级时,管理员可以选择将现有的在线用户和客户端会话迁移到持久会话。要使这工作,这些现有的会话需要存储在远程 Infinispan 中,或者存储在配置为 Keycloak 嵌入式缓存的 JDBC 持久性中的数据库中。不支持将 Keycloak 24 的内存中会话迁移,因为由于嵌入式 Infinispan 的主要版本升级,所有 Keycloak 实例都需要在升级之前关闭。

用户会话的迁移仅在升级到 Keycloak 25 时启用持久用户会话时才有效。如果您选择升级到 25 但未启用持久用户会话,则目前无法在以后触发现有会话的迁移。

如果通过配置更改在以后启用此功能,如果持久会话和非持久会话共存,则可能会导致与会话相关的 Keycloak 行为不确定。为了防止这种情况,请在第一个节点以启用功能的方式启动之前删除所有现有的在线用户和客户端会话。这意味着所有 Keycloak 节点都需要停止,并且如果使用了远程 Infinispan 缓存存储和嵌入式 Infinispan JDBC 持久性,则需要清除它们。

要迁移 Keycloak 升级期间的用户会话,请执行以下步骤

  1. 停止所有正在运行的旧 Keycloak 实例。

  2. 创建备份

    • 创建 Keycloak 数据库的备份。

    • 如果使用 JDBC 持久性,请创建该数据库的备份,以便您能够重试会话迁移。

    • 如果使用外部 Infinispan,请创建其数据的备份,以便您能够重试会话迁移。

  3. 使用启用了持久用户会话功能的新 Keycloak 实例启动。

    第一个启动的节点将

    1. 将数据库迁移到 Schema 版本 25。

    2. 将所有会话信息从远程 Infinispan 或为 Keycloak 嵌入式缓存配置的 JDBC 持久性复制到 Keycloak 的数据库中。

      数据将存储在 offline_user_sessionoffline_client_session 表中,其中 offline_flag 设置为 false

    3. 清除缓存。

      这包括清除外部 Infinispan 的缓存(如果使用了),以及清除 JDBC 持久性(如果使用了)。

  4. 更新 Keycloak 的缓存配置 XML,用于缓存 sessionsclientSessions

    • 如果使用 JDBC 持久性,请删除 JDBC 持久性的配置。

    • 如果远程 Infinispan 仅在单个站点设置中用于在 Keycloak 重新启动时保持用户会话,请删除这些缓存的远程 Infinispan 配置。

    如果在多站点设置中使用远程 Infinispan,您可以通过配置内存中的条目数量来减少外部 Infinispan 的资源消耗。使用 使用 Infinispan 运算符部署 Infinispan 以实现高可用性 指南中概述的设置。
  5. 滚动重启 Keycloak 以激活新的缓存配置 XML。

注销现有用户

在以前版本中,以及在禁用功能时,重新启动所有 Keycloak 节点将注销所有用户。要注销启用了 persistent-user-sessions 功能的 realm 的所有在线用户会话,请按以下步骤操作,与之前相同

  1. 登录到管理控制台。

  2. 选择菜单项会话

  3. 选择操作注销所有活动会话

嵌入式缓存的指标默认情况下处于启用状态

嵌入式缓存的指标现在默认情况下处于启用状态。要为延迟启用直方图,请将选项 cache-metrics-histograms-enabled 设置为 true

HTTP 端点的指标默认情况下处于启用状态

Keycloak 提供的指标现在包括以 http_server 开头的 HTTP 服务器指标。请参阅下面的示例。

http_server_active_requests 1.0
http_server_requests_seconds_count{method="GET",outcome="SUCCESS",status="200",uri="/realms/{realm}/protocol/{protocol}/auth"} 1.0
http_server_requests_seconds_sum{method="GET",outcome="SUCCESS",status="200",uri="/realms/{realm}/protocol/{protocol}/auth"} 0.048717142

使用新的选项 http-metrics-histograms-enabledhttp-metrics-slos 来启用默认直方图存储桶或服务级别目标 (SLO) 的特定存储桶。阅读有关 Prometheus 文档中的直方图 的更多信息,了解如何使用 http_server_requests_seconds_bucket 中提供的其他指标系列。

Argon2 密码散列

在 Keycloak 24 版本中,我们对密码哈希算法进行了更改,导致 CPU 使用率增加。为了解决这个问题,我们选择在非 FIPS 环境中使用不同的默认哈希算法 Argon2,它将 CPU 使用率恢复到 Keycloak 24 版本之前的水平。

预期整体 CPU 使用率提高,数据库活动暂时增加

Keycloak 高可用性指南中关于确定 CPU 和内存资源大小的概念已更新,以反映新的哈希默认值。

升级后,在基于密码的登录期间,用户的密码将使用新的哈希算法和哈希迭代重新哈希,作为一次性活动,并在数据库中更新。由于这会从 Keycloak 的内部缓存中清除用户,因此您还会在数据库级别看到读操作活动增加。随着越来越多的用户密码被重新哈希,这种数据库活动增加将随着时间的推移而减少。

更新的 JVM 垃圾回收设置

为了支持 Argon2 的内存密集型特性,我们已将默认 GC 从 ParallelGC 更新为 G1GC,以实现更好的堆利用率。请在升级后密切监控 JVM 堆利用率。根据您的特定工作负载,可能需要进行额外的调整。

限制使用 HTTP 响应时内存使用量

在某些情况下,例如 Keycloak 使用 HTTP 与外部服务器进行通信时,为了避免当这些提供者发送过多数据时出现拒绝服务,Keycloak 现在默认将响应限制为 10 MB。

用户可以通过设置提供程序配置选项 spi-connections-http-client-default-max-consumed-response-size 来配置此限制。

将使用过的响应限制为 1 MB
bin/kc.[sh|bat] --spi-connections-http-client-default-max-consumed-response-size=1000000

主机名验证策略

spi-truststore-file-hostname-verification-policy 和新的 tls-hostname-verifier 选项的默认值现在为 DEFAULT,而不是 WILDCARD。WILDCARD 和 STRICT 选项值已弃用 - 您应该改为直接依赖 DEFAULT。

WILDCARD 支持但 DEFAULT 不支持的行为:* 允许在子域名称中使用通配符(例如 *.foo.com)匹配任何内容,包括多级(例如 a.b.foo.com)。* 允许与众所周知的公共后缀匹配 - 例如 foo.co.gl 可能与 *.co.gl 匹配。

STRICT 支持但 DEFAULT 不支持的行为:* STRICT 在确定通配符是否匹配时,对以 2 个字母或 3 个字母的顶级域结尾的 2 个字母或 3 个字母的域使用一小部分排除列表(*.XXX.YY)。而 DEFAULT 使用来自 https://publicsuffix.org/list/ 的更完整的公共后缀规则和排除列表。

预计您不应依赖 WILDCARD 或 STRICT 选项的这些行为。

解决针对已过期的身份验证会话的“您已登录”问题

Keycloak 现在不会在身份验证会话过期且用户已登录时向最终用户显示消息“您已登录”。相反,它会将有关过期身份验证会话的错误重定向到客户端应用程序,以便客户端可以根据该错误采取行动并按照 服务器管理指南身份验证会话章节 中的说明重新启动身份验证。您可能需要考虑更新您的应用程序,使其能够处理此错误。

删除了一个模型模块

模块 org.keycloak:keycloak-model-legacy 模块在以前的版本中已弃用,并且在本版本中已删除。请改为使用 org.keycloak:keycloak-model-storage 模块。

XA 事务更改

  • 选项 transaction-xa-enabled 的默认值为 false,而不是 true。如果您需要 XA 事务支持,则现在需要显式将此选项设置为 true。

  • XA 事务恢复支持默认启用。事务日志将存储在 KEYCLOAK_HOME/data/transaction-logs 中。

删除了离线会话预加载

在之前的版本中已弃用后,现在删除了在启动时预加载离线会话的旧行为。

在运行时指定 cache 选项

选项 cachecache-stackcache-config-file 不再是构建选项,只能在运行时指定。这消除了执行构建阶段并由于它们而重建您的映像的需要。请注意,它们在 build 阶段不会被识别,因此您需要删除它们。

kcadm 和 kcreg 更改

kcadm 和 kcreg 解析和处理选项和参数的方式已更改。来自用法错误、错误选项或参数的错误消息可能与以前的版本略有不同。此外,用法错误将具有 2 而不是 1 的退出代码。

删除自定义用户属性索引

在按用户属性搜索用户时,Keycloak 不再搜索用户属性名称以强制执行小写比较。这意味着在搜索时现在将使用 Keycloak 对用户属性表进行的本机索引。如果您已创建了基于 `lower(name)` 的自己的索引以加快搜索速度,那么您现在可以删除它。

新的默认客户端范围 basic

名为 basic 的新客户端范围被添加为 realm 的“默认”客户端范围,因此将被添加到所有新创建的 OIDC 客户端。在迁移期间,客户端范围也会自动添加到所有现有的 OIDC 客户端。

此范围包含针对以下声明预先配置的协议映射器

  • sub(请参阅下面专门部分中的详细信息)

  • auth_time

这提供了额外的帮助,可以减少轻量级访问令牌中的声明数量,但也提供了配置始终自动添加的声明的机会。

如果您在某些 realm 中已经有了名为 basic 的客户端范围,那么新的客户端范围 basic 不会添加到您的 realm 中,也不会添加到任何客户端中。对于这种特殊情况,迁移将被忽略。在这种情况下,您需要在迁移到此 Keycloak 版本之前确保将您的客户端范围重命名为与 basic 不同的名称,或者您需要手动处理缺少的 subauth_time 声明(如果您需要它们在令牌中),并且您可能需要手动将相应的协议映射器添加到某些客户端范围。

删除了 session_state 声明

session_state 声明(包含与 sid 声明相同的值)现在已从所有令牌中删除,因为它不是 OpenID Connect 前端通道注销和 OpenID Connect 后端通道注销规范所必需的。session_state 声明仍将按照 OpenID Connect 会话管理规范出现在访问令牌响应中。

请注意,setSessionState() 方法也已从 IDToken 类中删除,取而代之的是 setSessionId() 方法,并且 getSessionState() 方法现在已弃用。

还包括一个新的 会话状态 (session_state) 映射器,可以将其分配给客户端范围(例如 basic 客户端范围)以恢复到旧的行为。

如果使用的是旧版本的 JS 适配器,则也应通过使用上面描述的客户端范围来使用 会话状态 (session_state) 映射器。

sub 声明是通过协议映射器添加到访问令牌中的

sub 声明(始终添加到访问令牌中)现在默认添加,但使用新的 主体 (sub) 协议映射器。

主体 (sub) 映射器在 basic 客户端范围内默认配置。因此,升级到此版本后不需要额外的配置。

如果您使用 成对主体标识符 映射器来映射访问令牌的 sub 声明,您可以考虑禁用或删除 主体 (sub) 映射器,但这并不严格需要,因为 主体 (sub) 协议映射器在 成对主体标识符 映射器之前执行,因此 pairwise 值将覆盖 主体 (sub) 映射器添加的值。这可能也适用于其他自定义协议映射器实现,这些实现覆盖 sub 声明,因为 主体 (sub) 映射器当前作为第一个协议映射器执行。

您可以使用 主体 (sub) 映射器仅为访问令牌、轻量级访问令牌和自检响应配置 sub 声明。IDToken 和 Userinfo 始终包含 sub 声明。

对于服务帐户,映射器没有效果,因为不存在用户会话,并且 sub 声明始终添加到访问令牌中。

Nonce 声明仅添加到 ID 令牌

Nonce 声明现在仅严格按照 OpenID Connect Core 1.0 规范添加到 ID 令牌中。如规范中所述,当在授权请求中发送相同的参数时,该声明在 ID 令牌 中是必需的。规范还建议在 刷新请求 后不要添加 nonce。以前,该声明被设置为所有令牌(访问、刷新和 ID)中的所有响应(包括刷新)。

软件中还包括一个新的 Nonce 向后兼容 映射器,可以将其分配给客户端范围以恢复到旧的行为。例如,JS 适配器在解决问题 #26651(在 24.0.0 版本中)之前,检查了所有令牌中返回的 nonce 声明。因此,如果使用的是旧版本的 JS 适配器,则应通过使用客户端范围将其添加到所需的客户端。

REFRESH_TOKEN 事件中的 userId 现在始终从用户会话中获取,而不是从刷新令牌中的 sub 声明中获取。REFRESH_TOKEN_ERROR 事件中的 userId 现在始终为 null。进行此更改的原因是,随着可选 sub 声明的引入,刷新令牌中 sub 声明的值可能为 null,或者在使用成对主体标识符或其他覆盖 sub 声明的方式时,它可能与实际用户 ID 不同。

但是,现在添加了一个 refresh_token_sub 详细信息,作为向后兼容,以便在 REFRESH_TOKEN_ERROR 事件中缺少 userId 的情况下获得有关用户的详细信息。

使用旧的 JavaScript 适配器

如果您在应用程序中将最新的 Keycloak 服务器与旧版本的 JavaScript 适配器一起使用,则可能会受到上面提到的令牌更改的影响,因为旧版本的 JavaScript 适配器依赖于 Keycloak 添加的声明,但这些声明不受 OIDC 规范支持。这包括

  • 如果使用 Keycloak Javascript 适配器 24.0.3 或更旧版本,则添加 会话状态 (session_state) 映射器

  • 如果使用的是比 Keycloak 24 更旧的 Keycloak Javascript 适配器,则添加 Nonce 向后兼容 映射器

您可以将协议映射器直接添加到相应的客户端或某个客户端范围,这可供依赖 Keycloak Javascript 适配器旧版本的客户端应用程序使用。有关更多详细信息,请参阅前面关于session_statenonce声明的部分。

默认http-pool-max-threads已减少

如果未设置http-pool-max-threads,则默认值为 50 或 4 x(可用处理器)中的较大者。以前,它默认为 200 或 8 x(可用处理器)中的较大者。对于大多数使用场景,减少任务线程数将导致略微提高性能,因为活跃线程之间的上下文切换次数更少。

指标和运行状况端点的管理端口

/health/metrics端点可在管理端口9000上访问,该端口默认情况下处于启用状态。这意味着这些端点不再暴露在标准 Keycloak 端口80808443上。

为了反映旧的行为,请使用属性--legacy-observability-interface=true,这将不会在管理端口上公开这些端点。但是,此属性已弃用,将在未来版本中删除,因此建议不要使用它。

管理界面使用与默认 Keycloak HTTP 服务器不同的 HTTP 服务器,可以单独配置它们。请注意,如果未为管理界面属性提供任何值,则会从默认 Keycloak HTTP 服务器继承这些属性。

有关更多详细信息,请参阅配置管理界面

转义组路径中的斜杠

Keycloak 从未在组路径中转义斜杠。因此,名为group/slash、作为top的子级的组使用完整路径/top/group/slash,这显然具有误导性。从本版本开始,服务器可以启动以执行对名称中这些斜杠的转义。

bin/kc.[sh|bat] start --spi-group-jpa-escape-slashes-in-group-path=true

转义字符是波浪号字符~。前面的示例导致路径/top/group~/slash。转义标记最后一个斜杠是名称的一部分,而不是层次结构分隔符。

转义目前默认情况下处于禁用状态,因为它代表了行为上的改变。尽管如此,建议启用转义,它可能在未来版本中成为默认值。

更改为类EnvironmentDependentProviderFactory

方法EnvironmentDependentProviderFactory.isSupported()已在多个版本中弃用,现在已被删除。

改为实现isSupported(Config.Scope config)

删除已弃用的 LinkedIn 提供程序

在版本 22.0.2 中,用于 LinkedIn 的 OAuh 2.0 社交提供程序被新的 OpenId Connect 实现替换。旧的提供程序已弃用但未删除,以防它在某些现有领域仍然有效。Keycloak 25.0.0 肯定删除了旧的提供程序及其关联的linkedin-oauth功能。从现在起,默认的LinkedIn社交提供程序是唯一可用的选项。

提高findGrantedResourcesfindGrantedOwnerResources查询的性能

RESOURCE_SERVER_RESOURCERESOURCE_SERVER_PERM_TICKET表具有超过 100k 个条目,并且用户被授予对超过 1k 个资源的访问权限时,这些查询的执行效率低下。查询已简化,并为requesterowner列引入了新的索引。

新索引都应用于RESOURCE_SERVER_PERM_TICKET表。如果该表当前包含超过 300,000 个条目,Keycloak 将在自动模式迁移期间默认情况下跳过索引的创建,而是将 SQL 语句记录在迁移期间的控制台中。在这种情况下,必须在 Keycloak 启动后手动在数据库中运行这些语句。

有关如何配置不同限制的详细信息,请参阅升级指南

AccessTokenIDTokenJsonWebToken类中删除已弃用的方法

以下方法已从AccessToken类中删除

  • expiration。改用exp方法。

  • notBefore。改用nbf方法。

  • issuedAt。改用iat方法。

以下方法已从IDToken类中删除

  • getAuthTimesetAuthTime。分别使用getAuth_timesetAuth_time方法。

  • notBefore。改用nbf方法。

  • issuedAt。改用iat方法。

  • setSessionState。改用setSessionId方法(有关session_state声明的详细信息,请参阅上面的部分)

以下方法已从JsonWebToken类中删除

  • expiration。改用exp方法。

  • notBefore。改用nbf方法。

  • issuedAt。改用iat方法。

您还应该预期expnbf声明未在令牌中设置,因为它们是可选的。以前,这些声明被设置为0的值,这没有多大意义,因为它们的值应该是有效的NumericDate

方法getExp已添加到SingleUseObjectKeyModel

由于从AccessTokenIDTokenJsonWebToken中删除了已弃用的方法,因此SingleUseObjectKeyModel也发生了变化,以保持与与过期值相关的方法名称的一致性。

以前getExpiration方法现在已弃用,您应该优先使用新引入的getExp方法以避免 2038 年后的溢出。

方法encodePasswordHashProvider上已弃用

接口org.keycloak.credential.hash.PasswordHashProvider上的方法String encode(String rawPassword, int iterations)已弃用。该方法将在 Keycloak 的未来某个版本中删除。它可能是 Keycloak 27 版本。

已删除CollectionUtil交叉方法

已删除方法org.keycloak.common.util.CollectionUtil.intersection。您应该改用现有集合上的java.util.Collection.retainAll

Resteasy 实用程序类已弃用

org.keycloak.common.util.Resteasy已弃用。您应该使用org.keycloak.util.KeycloakSessionUtil来获取KeycloakSession

强烈建议您避免通过创建自定义提供程序以外的方式获取KeycloakSession

会话生命周期和空闲计算中的细微变化

在以前的版本中,会话最大生命周期和空闲超时计算在验证会话是否仍然有效时略有不同。由于现在该验证使用与项目其余部分相同的代码。

如果会话使用记住我功能,则空闲超时和最大生命周期是普通 SSO 和记住我配置值之间的最大值。

外部 Infinispan 要求

Keycloak 现在要求外部 Infinispan 部署的 Infinispan 服务器版本至少为 15.0.0。外部 Infinispan 部署受 HA 指南中概述的多站点设置的支持。

Oracle 数据库驱动程序不是分发的一部分

Oracle 数据库 JDBC 驱动程序不再是 Keycloak 分发的一部分。如果您希望使用 Oracle 数据库,则必须手动安装与您的特定环境兼容的 Oracle 驱动程序版本。有关此过程的说明,请参阅配置数据库指南。

已弃用的主题变量

以下变量已在管理主题中弃用,并将

  • authServerUrl。改用serverBaseUrl

  • authUrl。改用adminBaseUrl

以下变量已在帐户主题中弃用,并将

  • authServerUrl。改用serverBaseUrl,请注意serverBaseUrl不包含尾部斜杠。

  • authUrl。改用serverBaseUrl,请注意serverBaseUrl不包含尾部斜杠。

获取和设置客户端会话中当前刷新令牌的方法现已弃用

接口org.keycloak.models.AuthenticatedClientSessionModel中的方法String getCurrentRefreshToken()void setCurrentRefreshToken(String currentRefreshToken)int getCurrentRefreshTokenUseCount()void setCurrentRefreshTokenUseCount(int currentRefreshTokenUseCount)已弃用。它们已被类似的方法替换,这些方法需要标识符作为参数,例如getRefreshToken(String reuseId),用于管理客户端会话中的多个刷新令牌。这些方法将在 Keycloak 的未来某个版本中删除。它可能是 Keycloak 27 版本。

迁移到 24.0.4

通过管理用户 API 更新用户时,对用户属性进行部分更新不再受支持

通过管理用户 API 更新用户属性时,在更新用户属性(包括usernameemailfirstNamelastName等根属性)时,不能执行部分更新。

如果通过管理用户 API 更新用户属性,但不传递管理员具有写入权限的所有属性,则将删除缺失的属性。另一方面,如果属性被标记为对管理员只读,则不发送该属性不会删除它。

有关用户配置文件设置的详细信息,请参阅用户配置文件文档

迁移到 24.0.3

org.keycloak.userprofile.UserProfileDecorator接口的更改

为了在领域内正确支持多个用户存储提供程序,org.keycloak.userprofile.UserProfileDecorator接口已更改。

decorateUserProfile方法不再在第一次解析用户配置文件配置(并将其缓存)时调用,而是在每次通过用户配置文件提供程序管理用户时调用。因此,该方法更改了其约定为

List<AttributeMetadata> decorateUserProfile(String providerId, UserProfileMetadata metadata)

与之前的约定和行为不同,此方法仅对从其中加载用户的用户存储提供程序调用。

使用通配符时重定向 URI 验证中的更改

由于安全问题,如果传递的重定向 URI 包含userinfo部分或其path访问父目录(/../),则重定向 URI 验证现在执行精确字符串匹配(不涉及通配符)。

完整通配符*仍可作为开发中的有效重定向在具有这些特征的 http(s) URI 中使用。在生产环境中,需要为任何类型的 URI 配置不带通配符的精确有效重定向 URI。

请注意,通配符有效重定向 URI 不建议用于生产环境,也不受 OAuth 2.0 规范的涵盖。

已弃用的用于删除凭据的帐户 REST 端点

用于删除用户凭据的帐户 REST 端点已弃用。从本版本开始,帐户控制台不再使用此端点。它被替换为由帐户控制台在用户想要删除用户的凭据时触发的“删除凭据”应用程序启动操作。

迁移到 24.0.2

密码哈希更改

Keycloak 24.0.0 的发行说明已更新,其中包含对预期性能影响的更正描述以及尺寸指南。

迁移到 24.0.0

欢迎主题的更改

“欢迎”主题已更新为使用新布局,现在使用 PatternFly 5 而不是 PatternFly 3。如果您正在扩展主题或提供自己的主题,您可能需要按如下方式更新它

从 PatternFly 3 迁移到 PatternFly 5

欢迎主题是 Keycloak 中比较过时的主题之一。它最初基于 PatternFly 3,但现在已更新为使用 PatternFly 5,在此过程中跳过了主要版本。如果您的自定义主题扩展了内置主题,您需要将其更新为使用 PatternFly 5 语法。有关详细信息,请参阅 PatternFly 5 文档

如果您在自己的自定义主题(未扩展内置主题)中仍然使用 PatternFly 3,您可以继续使用它,但 PatternFly 3 支持将在未来的版本中删除,因此您应该尽快考虑迁移到 PatternFly 5。

自动重定向到管理控制台

如果启用了管理控制台,则欢迎页面将在管理用户已存在的情况下自动重定向到管理控制台。可以通过在您的 `theme.properties` 文件中设置 `redirectToAdmin` 来修改此行为。默认情况下,该属性设置为 `false`,除非您正在扩展内置主题,在这种情况下,该属性设置为 `true`。

这些属性以前用于现在不再存在的导航元素。如果您正在扩展内置主题,您需要从您的 `theme.properties` 文件中删除这些属性,因为它们不再有任何效果。

资产现在从“公共”资源加载

现在从“公共”资源而不是主题资源加载背景、徽标和收藏夹图标等图像。此更改意味着,如果您正在扩展内置主题,并且正在覆盖这些图像,您需要将它们移动到主题的“公共”资源中,并更新您的 `theme.properties` 文件以包含新路径

# This defaults to 'common/keycloak' if not set.
import=common/your-theme-name

帐户控制台主题定制的更改

如果您以前正在扩展现已弃用的帐户控制台主题版本 2,您需要更新您的主题以使用帐户控制台主题的新版本 3。帐户控制台主题的新版本在自定义方式方面有一些更改。要从头开始,您可以按照新的 自定义快速入门 进行操作。

要移动您的自定义主题,首先将 `parent` 更改为新主题

# Before
parent=keycloak.v2

# After
parent=keycloak.v3

如果您有任何自定义 React 组件,您将直接导入 React,而不是使用相对路径

// Before
import * as React from "../../../../common/keycloak/web_modules/react.js";

// After
import React from "react";

如果您使用 `content.json` 来自定义主题,则该文件结构有一些更改,具体来说

  • `content` 属性已重命名为 `children`。

  • `id`、`icon` 和 `componentName` 属性已被删除,因为 `modulePath` 提供了相同的功能。

Keycloak JS 导入可能需要更新

如果您直接从 Keycloak 服务器加载 Keycloak JS,则可以安全地忽略本节。如果您从 NPM 包加载 Keycloak JS 并且正在使用 Webpack、Vite 等打包器,您可能需要对代码进行一些更改。Keycloak JS 包现在使用 `package.json` 文件中的 `exports` 字段。这意味着您可能需要更改导入内容

// Before
import Keycloak from 'keycloak-js/dist/keycloak.js';
import AuthZ from 'keycloak-js/dist/keycloak-authz.js';

// After
import Keycloak from 'keycloak-js';
import AuthZ from 'keycloak-js/authz';

功能更改

不允许在 `--features` 和 `--features-disabled` 列表中同时包含相同的功能。该功能应仅出现在一个列表中。

在 `--features` 列表中使用无版本的功能名称,例如 `docker`,将允许为您的用户启用最受支持/最新的功能版本。如果您需要跨版本更可预测的行为,请改为引用您想要的特定版本,例如 `docker:v1`。

用户资料更改

默认情况下启用用户资料

用户资料功能现在默认情况下已启用。`declarative-user-profile` 功能不再可用,因为假定用户资料已启用。因此,**用户资料启用** 开关已从**领域设置** 中删除,并被**未管理的属性** 替换。从先前版本迁移时,行为如下

  • 对于**用户资料启用** 设置为**开启** 的部署,升级后**未管理的属性** 将设置为**关闭**。因此,仅用户资料明确支持的用户属性将被允许。

  • 对于**用户资料启用** 设置为**关闭** 的部署(这也是默认情况下禁用 `declarative-user-profile` 功能的部署的默认设置,该功能是默认禁用的),升级后**未管理的属性** 将设置为**开启**。因此,行为应与先前版本的禁用用户资料基本相同。**属性** 选项卡将保留在管理控制台的用户详细信息部分。此外,用户现在可以通过注册页面和更新资料页面等 UI 页面设置任意属性,只要特定自定义主题支持即可。自定义主题应也能像以前一样工作。但是,请考虑更新您的主题以使用用户资料,甚至在需要添加自定义属性的情况下,也可能删除您的自定义主题。请参阅下一节关于主题的内容。此外,请考虑将**未管理的属性** 切换为**关闭**,或者仅为管理员启用此开关,以便您可以主要依靠使用已管理的属性。

有关**未管理的属性** 的详细信息,请参阅 用户资料文档

默认验证

默认用户资料配置包含一组针对基本预定义字段的默认验证。这些验证以前在默认情况下禁用 `declarative-user-profile` 功能时不存在。如果您由于向后兼容性出现问题,可以根据您的需要更改默认验证器。默认验证器如下

  • `username`、`email`、`firstName` 和 `lastName` 属性的最大长度为 255 个字符。这些验证在以前版本中也间接存在,因为对那些长度最大为 255 个字符的字段的 `USER_ENTITY` 表的数据库约束。但是,在使用用户存储提供者时,以前可能可以使用更长的值。

  • `username` 属性的最小长度为三个字符。用户名默认情况下还具有 `username-prohibited-characters` 和 `up-username-not-idn-homograph` 验证器,这些验证器在以前版本中不存在。有关这些属性的详细信息,请参阅 用户资料文档的验证部分。请注意,用户名默认情况下不可编辑,除非您拥有领域开关 `Edit username enabled`。此更改意味着使用不正确用户名存在的现有用户仍应起作用,并且不会强制他们更新用户名。但是,新用户在通过管理员 REST API 注册或创建时,将被迫使用正确的用户名。

  • `firstName` 和 `lastName` 属性具有 `person-name-prohibited-characters` 验证器,这些验证器在以前版本中不存在。有关这些属性的详细信息,请参阅 用户资料文档的验证部分。请注意,名字和姓氏默认情况下都是可编辑的,因此,已经从以前版本中获得了这种不正确的名字/姓氏的用户,在更新用户资料时将被迫更新它们。

包含奇怪字符的用户属性名称

在以前版本中,您可以创建具有 `some:attribute` 或 `some/attribute` 等属性名称的用户。用户资料有意不允许您在用户资料配置中创建具有此类奇怪名称的属性。因此,您可能需要为您的领域配置 `未管理的属性`,并为管理员(理想情况下)或最终用户(如果确实需要)启用未管理的属性。尽管强烈建议避免使用此类属性名称。

默认情况下启用“验证资料”必需操作

对于新领域,`verify-profile` 必需操作默认情况下已启用。但是,当您从先前版本迁移时,现有领域将与以前具有相同的 `verify-profile` 操作状态,这通常意味着已禁用,因为它在先前版本中默认情况下已禁用。有关此必需操作的详细信息,请参阅 用户资料文档

对用户资料 SPI 的重大更改

如果您在扩展程序中使用用户资料 SPI,您可能会受到本版本中引入的 API 更改的影响。

`org.keycloak.userprofile.Attributes` 接口包含以下更改

  • 方法 `getValues` 已重命名为 `get`,使其更符合来自常规 Java `Map` 的相同操作

  • 方法 `isRootAttribute` 已移至实用程序类 `org.keycloak.userprofile.UserProfileUtil.isRootAttribute`

  • 方法getFirstValue已重命名为getFirst,以减少冗长。

  • 方法getReadable(boolean)已删除,现在所有属性(包括根属性)只要具有读取权限,就会被返回。

基于用户资料和领域渲染页面的 Freemarker 模板变更

在此版本中,以下模板已更新,以便能够根据设置为领域的用户信息配置动态渲染属性。

  • login-update-profile.ftl

  • register.ftl

  • update-email.ftl

这些模板分别用于渲染更新资料页面(当为用户启用更新资料所需的操作时)、注册页面和更新电子邮件页面(当启用UPDATE_EMAIL功能时)。

如果您使用自定义主题来更改这些模板,它们将按预期工作,因为只有内容已更新。但是,我们建议您了解如何配置{声明式用户资料},并可能通过使用此功能提供的所有功能来避免更改内置模板。

此外,declarative-user-profile功能在以前版本中用于渲染相同流程页面的模板已不再需要,并在此版本中被删除。

  • update-user-profile.ftl

  • register-user-profile.ftl

如果您在以前版本中使用declarative-user-profile功能并对上述模板进行自定义,请相应地更新login-update-profile.ftlregister.ftl

首次通过代理登录时的更新资料页面新增 Freemarker 模板

在此版本中,当用户首次通过代理进行身份验证时,服务器将使用idp-review-user-profile.ftl模板渲染更新资料页面。

在以前的版本中,用于在首次代理登录流程期间更新资料的模板是login-update-profile.ftl,它与用户身份验证到领域时用于更新资料的模板相同。

通过为每个流程使用单独的模板,可以更清楚地区分模板实际使用的流程,而不是共享同一个模板,这可能会引入意外的更改和行为,而这些更改和行为应该只影响特定流程的页面。

如果您对login-update-profile.ftl模板进行了自定义,以自定义用户通过代理进行身份验证时如何更新其资料,请确保将您的更改移至新模板。

信任库变更

spi-truststore-file-*选项和与信任库相关的选项https-trust-store-*已弃用。因此,请使用信任库材料的新默认位置conf/truststores,或使用truststore-paths选项指定您想要的路径。有关详细信息,请参阅相关的指南

tls-hostname-verifier属性应代替spi-truststore-file-hostname-verification-policy属性。

更改的附带影响是,现在信任库提供程序始终配置了一些证书(至少存在默认的 java 可信证书)。这种新行为可能会影响 Keycloak 的其他部分。

例如,如果证明传递配置为直接验证,则webauthn注册可能会失败。以前,如果信任库提供程序未配置,则不会验证传入的证书。但现在,始终执行此验证。注册失败并显示无效证书路径错误,因为身份验证器发送的证书链不受 Keycloak 的信任。身份验证器的证书颁发机构需要存在于信任库提供程序中才能正确执行证明。

已弃用的--proxy选项

--proxy选项已弃用,将在未来版本中删除。下表说明了弃用选项如何映射到支持的选项。

已弃用的用法 新用法

kc.sh(未设置proxy选项)

kc.sh

kc.sh --proxy none

kc.sh

kc.sh --proxy edge

kc.sh --proxy-headers forwarded|xforwarded --http-enabled true

kc.sh --proxy passthrough

kc.sh --hostname-port 80|443(取决于是否使用 HTTPS)

kc.sh --proxy reencrypt

kc.sh --proxy-headers forwarded|xforwarded

为了加强安全,--proxy-headers选项不允许同时选择forwardedxforwarded值(以前--proxy edge--proxy reencrypt就是这样)。
使用代理标头选项时,请确保您的反向代理正确设置并覆盖ForwardedX-Forwarded-*标头。要设置这些标头,请参阅您的反向代理的文档。错误配置会导致 Keycloak 暴露于安全漏洞中。

您也可以在使用 Operator 时设置代理标头。

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: example-kc
spec:
  ...
  proxy:
    headers: forwarded|xforwarded
如果未指定proxy.headers字段,则 Operator 会通过默认情况下隐式设置proxy=passthrough来回退到之前的行为。这会导致服务器日志中出现弃用警告。此回退将在未来版本中删除。

管理 API 和账户上下文中的用户表示形式变更

org.keycloak.representations.idm.UserRepresentationorg.keycloak.representations.account.UserRepresentation表示类都已更改,以便在分别将表示形式有效负载提取或发送到管理和账户 API 时,根用户属性(如usernameemailfirstNamelastNamelocale)具有一致的表示形式。

usernameemailfirstNamelastNamelocale属性已移动到新的org.keycloak.representations.idm.AbstractUserRepresentation基类。

此外,getAttributes方法的目标是仅表示自定义属性,因此您不应期望此方法返回的映射中包含任何根属性。此方法主要针对客户端在更新或提取给定用户的任何自定义属性时使用。

为了解析所有属性(包括根属性),添加了新的getRawAttributes方法,以便生成的映射还包含根属性。但是,此方法无法从表示形式有效负载中获取,它旨在由服务器在管理用户资料时使用。

https-client-auth是构建时选项

选项https-client-auth一直被视为运行时选项,但 Quarkus 不支持此选项。此选项需要在构建时而不是在运行时处理。

离线会话和远程会话的顺序加载

从本版本开始,Keycloak 集群的第一个成员将顺序加载远程会话,而不是并行加载。如果启用了离线会话预加载,那么这些会话也将顺序加载。

以前的代码会导致启动时集群中资源消耗过高,并且难以在生产环境中进行分析,如果在加载过程中重新启动节点,可能会导致复杂的故障场景。因此,它被更改为顺序会话加载。

对于离线会话,本版本和先前版本的 Keycloak 中的默认行为是按需加载这些会话,与尝试并行预加载它们相比,这在处理大量离线会话时可以更好地扩展。使用此默认设置的设置不受离线会话加载策略更改的影响。已启用离线会话预加载的设置应迁移到禁用离线会话预加载的设置。

已弃用的离线会话预加载

Keycloak 的默认行为是按需加载离线会话。在启动时预加载它们的老式行为现在已弃用,因为在启动时预加载它们在处理越来越多的会话时无法很好地扩展,并会增加 Keycloak 的内存使用量。老式行为将在未来版本中删除。

要在老式行为被弃用但尚未删除的情况下重新启用它,请使用功能标志和 SPI 选项,如下所示

bin/kc.[sh|bat] start --features-enabled offline-session-preloading --spi-user-sessions-infinispan-preload-offline-sessions-from-database=true

UserSessionProvider 的 API 已弃用方法getOfflineUserSessionByBrokerSessionId(RealmModel realm, String brokerSessionId)。请使用getOfflineUserSessionByBrokerUserIdStream(RealmModel, String brokerUserId)代替此方法,首先获取用户的会话,然后根据需要按代理会话 ID 进行筛选。

Infinispan 指标使用标签表示缓存管理器和缓存名称

当为 Keycloak 的嵌入式缓存启用指标时,指标现在使用标签表示缓存管理器和缓存名称。

没有标签的旧指标示例
vendor_cache_manager_keycloak_cache_sessions_statistics_approximate_entries_in_memory{cache="sessions",node="..."}
带有标签的新指标示例
vendor_statistics_approximate_entries_in_memory{cache="sessions",cache_manager="keycloak",node="..."}

要为安装恢复更改,请使用自定义 Infinispan XML 配置,并将配置更改如下

<metrics names-as-tags="false" />

用户属性值长度扩展

从本版本开始,Keycloak 支持存储和按用户属性值进行搜索,这些属性值大于 255 个字符,而这在以前是限制。

在允许用户更新属性的设置中(例如,通过账户控制台),请通过添加验证来防止拒绝服务攻击。确保不允许使用未管理的属性,并且所有可编辑的属性都具有限制输入长度的验证。

对于未管理的属性,最大长度为 2048 个字符。对于管理属性,默认最大长度为 2048 个字符。管理员可以通过添加类型为length的验证器来更改此设置。

Keycloak 在其内部缓存中缓存与用户相关的对象。使用更长的属性会增加缓存消耗的内存。因此,建议限制长度属性的大小。考虑将大型对象存储在 Keycloak 之外,并通过 ID 或 URL 对其进行引用。

此更改在USER_ATTRIBUTEFED_USER_ATTRIBUTE表中添加了新索引。如果这些表包含超过 300000 个条目,则 Keycloak 会在自动模式迁移期间默认跳过索引创建,并在启动 Keycloak 之后在控制台中记录 SQL 语句以手动应用。有关如何配置不同限制的详细信息,请参阅升级指南

新添加的索引USER_ATTR_LONG_VALUES_LOWER_CASEFED_USER_ATTR_LONG_VALUES_LOWER_CASE可能会超过 Oracle 设置的 30 个字符的最大限制,如果数据库在兼容模式下运行。从 Oracle 版本 12.2 开始,支持更长的索引名称。
LDAP 的其他迁移步骤

这适用于符合以下所有条件的安装

  • LDAP 目录中的用户属性大于 2048 个字符或大于 1500 字节的二进制属性。

  • 属性由管理员或用户通过管理控制台、API 或账户控制台更改。

要能够通过 UI 和 REST API 启用更改这些属性,请执行以下步骤

  1. 将上述识别出的属性声明为领域的用户资料中的管理属性。

  2. 为上一步中添加的每个属性定义length验证器,指定属性值的所需最小长度和最大长度。对于二进制值,将预期的二进制长度增加 33%,以计算 Keycloak 内部对二进制值的 base64 编码的开销。

自定义用户存储提供程序的其他迁移步骤

这适用于符合以下所有条件的安装

  • 将 MariaDB 或 MySQL 作为 Keycloak 的数据库运行。

  • FED_USER_ATTRIBUTE 中,VALUE 列中的内容大于 2048 个字符的条目。此表用于启用了联合身份验证的自定义用户提供程序。

  • 长属性由管理员或用户通过管理控制台或帐户控制台进行更改。

要能够通过 UI 和 REST API 启用更改这些属性,请执行以下步骤

  1. 将上述识别出的属性声明为领域的用户资料中的管理属性。

  2. 为上一步中添加的每个属性定义一个 length 验证器,指定属性值的所需最小长度和最大长度。

管理员发送验证电子邮件 API 现在使用相同的电子邮件验证模板

PUT /admin/realms/{realm}/users/{id}/send-verify-email

在此版本中,API 将使用 email-verification.ftl 模板,而不是 executeActions.ftl 模板。

升级前
Perform the following action(s): Verify Email
升级后
Confirm validity of e-mail address [email protected].

如果您已自定义 executeActions.ftl 模板来修改用户使用此 API 验证电子邮件的方式,请确保将您的修改转移到新模板中。

将引入一个名为 lifespan 的新参数,以允许覆盖默认的生存期值(12 小时)。

如果您更喜欢之前的行为,请使用 execute-actions-email API,如下所示。

PUT /admin/realms/{realm}/users/{id}/execute-actions-email

["VERIFY_EMAIL"]

删除用于 SAML 加密的已弃用模式

版本 21 中引入的 SAML 加密兼容模式现已删除。系统属性 keycloak.saml.deprecated.encryption 不再由服务器管理。仍然使用旧签名密钥进行加密的客户端应从新的 IDP 配置元数据中更新密钥。

密码散列更改

在此版本中,我们调整了密码散列默认值,以匹配 OWASP 密码存储建议

作为此更改的一部分,默认密码散列提供程序已从 pbkdf2-sha256 更改为 pbkdf2-sha512。此外,基于 pbkdf2 的密码散列算法的默认散列迭代次数已更改如下:

提供程序 ID 算法 旧迭代次数 新迭代次数

pbkdf2

PBKDF2WithHmacSHA1

20.000

1.300.000

pbkdf2-sha256

PBKDF2WithHmacSHA256

27.500

600.000

pbkdf2-sha512

PBKDF2WithHmacSHA512

30.000

210.000

如果领域未明确配置具有 hashAlgorithmhashIterations 的密码策略,则新配置将在下次基于密码的登录时生效,或在创建或更新用户密码时生效。

新密码散列配置的性能

在配备 Intel i9-8950HK CPU (12) @ 4.800GHz 的机器上进行的测试产生了以下散列 1000 个密码的 ⌀ 时间差(来自 3 次运行的平均值)。请注意,PBKDF2WithHmacSHA1 的平均持续时间是使用较少的密码计算的,因为运行时间很长。

提供程序 ID 算法 旧持续时间 新持续时间 差异

pbkdf2

PBKDF2WithHmacSHA1

122ms

3.114ms

+2.992ms

pbkdf2-sha256

PBKDF2WithHmacSHA256

20ms

451ms

+431ms

pbkdf2-sha512

PBKDF2WithHmacSHA512

33ms

224ms

+191ms

pbkdf2 提供程序的用户可能需要显式减少散列迭代次数才能恢复可接受的性能。这可以通过在领域的密码策略中明确配置散列迭代次数来完成。

预计整体 CPU 使用率增加和数据库活动暂时增加

Keycloak 高可用性指南中有关 CPU 和内存资源大小的说明已更新,以反映新的散列默认值。在我们的测试中,每次基于密码的登录的 CPU 使用率增加了五倍,其中包括更改的密码散列和未更改的 TLS 连接处理。由于 Keycloak 的其他活动(如刷新访问令牌和客户端凭证授予)的平均效应,整体 CPU 增加量应约为两到三倍。但这取决于安装的独特工作负载。

升级后,在基于密码的登录期间,用户的密码将使用新的散列算法和散列迭代次数重新散列,作为一次性活动,并在数据库中更新。由于这会从 Keycloak 的内部缓存中清除用户,因此您还会看到数据库级别的读取活动增加。随着越来越多的用户密码被重新散列,这种数据库活动增加将随着时间的推移而减少。

如何继续使用旧的 pbkdf2-sha256 密码散列?

要保持领域的旧密码散列,请在领域密码策略中明确指定 hashAlgorithmhashIterations

  • 散列算法:pbkdf2-sha256

  • 散列迭代次数:27500

运算符引用的资源轮询

现在将通过 Keycloak CR 引用的 Secrets 和 ConfigMaps 轮询更改,而不是通过 API 服务器进行监视。更改可能需要大约 1 分钟才能检测到。

这样做是为了不需要对这些资源进行标签操作。升级后,如果任何 Secret 仍然具有 operator.keycloak.org/component 标签,则可以将其删除或忽略。

为迁移重命名 JPA 提供程序配置选项

在删除 Map Store 后,以下配置选项已重命名:

  • spi-connections-jpa-legacy-initialize-emptyspi-connections-jpa-quarkus-initialize-empty

  • spi-connections-jpa-legacy-migration-exportspi-connections-jpa-quarkus-migration-export

  • spi-connections-jpa-legacy-migration-strategyspi-connections-jpa-quarkus-migration-strategy

重命名模型模块

在删除 Map Store 后,以下模块已重命名:

  • org.keycloak:keycloak-model-legacy-privateorg.keycloak:keycloak-model-storage-private

  • org.keycloak:keycloak-model-legacy-servicesorg.keycloak:keycloak-model-storage-services

以及 org.keycloak:keycloak-model-legacy 模块已弃用,将在下一个版本中被 org.keycloak:keycloak-model-storage 模块取代。

临时锁定日志已替换为事件

现在有一个新的事件 USER_DISABLED_BY_TEMPORARY_LOCKOUT,当用户被暴力保护程序暂时锁定时,会触发该事件。ID 为 KC-SERVICES0053 的日志已被删除,因为新的事件以结构化的形式提供信息。

由于这是一个成功事件,因此新事件默认情况下在 DEBUG 级别进行记录。使用设置 spi-events-listener-jboss-logging-success-level(如服务器管理指南的事件监听器章节中所述)更改所有成功事件的日志级别。

要触发自定义操作或自定义日志条目,请编写自定义事件监听器,如服务器开发者指南中的事件监听器 SPI 中所述。

运算符自定义属性键

运算符用于高级配置的属性键已从 operator.keycloak 更改为 kc.operator.keycloak

Keycloak CR 资源选项

当 Keycloak CR 和 KeycloakRealmImport CR 中未指定 resources 选项时,将使用默认值。Keycloak 部署和领域导入作业的默认 requests 内存设置为 1700MiBlimits 内存设置为 2GiB

对 cookie 的更新

作为 Keycloak 中重构 cookie 处理的一部分,对 cookie 设置方式进行了一些更改

  • 如果请求是通过安全上下文,则所有 cookie 现在都将设置 secure 属性

  • WELCOME_STATE_CHECKER cookie 现在设置为 SameSite=Strict

对于自定义扩展,可能需要进行一些更改

  • LocaleSelectorProvider.KEYCLOAK_LOCALE 已弃用,因为 cookie 现在通过 CookieProvider 进行管理

  • HttpResponse.setWriteCookiesOnTransactionComplete 已删除

  • HttpCookie 已弃用,请改用 NewCookie.Builder

  • ServerCookie 已弃用,请改用 NewCookie.Builder

内部算法已从 HS256 更改为 HS512

Keycloak 用于对内部令牌(Keycloak 本身使用,例如刷新令牌或操作令牌)进行签名的算法已从 HS256 更改为更安全的 HS512。现在为领域添加了一个名为 hmac-generated-hs512 的新密钥提供程序。请注意,在迁移的领域中,将保留旧的 hmac-generated 提供程序和旧的 HS256 密钥,并且仍然验证在升级之前发出的令牌。HS256 提供程序可以在没有更多旧令牌存在时手动删除,方法是按照旋转密钥指南进行操作。

在容器中运行时不同的 JVM 内存设置

在容器中运行时,JVM 选项 -Xms-Xmx 已被 -XX:InitialRAMPercentage-XX:MaxRAMPercentage 取代。Keycloak 不再使用静态的最大堆大小设置,而是将最大堆大小指定为容器总内存的 70%。

由于堆大小是根据容器的总内存动态计算的,因此您应始终设置容器的内存限制。

如果未设置内存限制,则内存消耗会迅速增加,因为最大堆大小会增长到容器总内存的 70%。

有关更多详细信息,请参阅在容器中运行 Keycloak 指南。

GELF 日志处理程序已弃用

随着提供与 GELF 集成的底层库的弃用,Keycloak 将不再开箱即用地支持 GELF 日志处理程序。此功能将在将来的版本中删除。如果您需要外部日志管理,请考虑使用文件日志解析。

迁移到 23.0.5

jboss-logging 事件消息中的更改

由于问题 #25078jboss-logging 消息值现在被引用(默认情况下为字符 ")并被清理以防止任何换行符。提供程序中有两个新的选项(spi-events-listener-jboss-logging-sanitizespi-events-listener-jboss-logging-quotes),允许您自定义新行为。例如,要同时避免清理和引用,可以以这种方式启动服务器

./kc.sh start --spi-events-listener-jboss-logging-sanitize=false --spi-events-listener-jboss-logging-quotes=none ...

有关选项的更多信息,请参阅所有提供程序配置指南。

迁移到 23.0.4

修复 Groups.getSubGroups briefRepresentation 参数的处理

版本 23.0.0 在 Groups 资源上引入了一个新的端点 getSubGroups(“子项”),其中参数 briefRepresentation 的含义是检索子组的完整表示。现在该含义已更改为返回简要表示。

迁移到 23.0.2

客户端的有效重定向URI始终使用精确字符串匹配进行比较

1.8.0 版本在将重定向 URI 与客户端指定的有效重定向进行比较时,引入了对主机名和方案进行小写转换。不幸的是,它在所有协议中并没有完全发挥作用,例如,主机名在 `http` 中被转换为小写,但在 `https` 中却没有。由于 OAuth 2.0 安全最佳实践 建议使用精确字符串匹配来比较 URI,Keycloak 将遵循该建议,从现在起,有效重定向将使用精确的大小写进行比较,即使对于主机名和方案也是如此。

对于依赖旧行为的 realm,其客户端的有效重定向 URI 现在应该为每个应该被服务器识别的 URI 保存单独的条目。

虽然这在配置客户端时引入了更多步骤和冗长性,但新的行为使更安全的部署成为可能,因为基于模式的检查通常是安全问题的根源。这些问题源于它们的实现方式和配置方式。

操作员 -secrets-store 密钥

旧版本的 operator 创建了一个密钥来跟踪被观察的密钥。新版本的 operator 不再使用 -secrets-store 密钥,因此可以将其删除。

如果您使用的是 23.0.0 或 23.0.1,并在 operator 日志中看到 "org.keycloak.operator.controllers.KeycloakAdminSecretDependentResource → java.lang.IllegalStateException: More than 1 secondary resource related to primary",则可以删除 -secrets-store 密钥,或者升级到 23.0.2 版本,该版本不再存在此问题。

迁移到 23.0.0

在 OAuth 2.0/OpenID Connect 身份验证响应中添加 iss 参数

RFC 9207 OAuth 2.0 授权服务器发行者标识规范在 OAuth 2.0/OpenID Connect 身份验证响应中添加了参数 `iss`,以实现安全的授权响应。

在过去版本中,我们没有此参数,但现在 Keycloak 根据规范要求默认情况下添加了此参数。

但是,一些 OpenID Connect/OAuth2 适配器,尤其是旧版本的 Keycloak 适配器,可能会遇到此新参数的问题。

例如,该参数将始终出现在客户端应用程序成功身份验证后的浏览器 URL 中。在这些情况下,禁用将 `iss` 参数添加到身份验证响应中可能很有用。这可以通过 Keycloak 管理控制台中的特定客户端完成,在客户端详细信息中的 `OpenID Connect 兼容性模式` 部分,如 与旧版适配器的兼容性 中所述。存在专用的 `从身份验证响应中排除发行者` 开关,可以将其打开以防止将 `iss` 参数添加到身份验证响应中。

通配符处理

JPA 允许在搜索时使用通配符 `%` 和 `_`,而其他提供者(如 LDAP)只允许使用 `*`。由于 `*` 是 LDAP 中的自然通配符,因此它在所有地方都有效,而在 JPA 中,它只在搜索字符串的开头和结尾处有效。从本版本开始,唯一的通配符是 `*`,它在所有提供者中,在搜索字符串的所有地方都一致有效。特定提供者中的所有特殊字符,如 JPA 的 `%` 和 `_`,都会被转义。对于使用引号添加的精确搜索,例如 `“w*ord”`,其行为与以前版本保持一致。

主题的语言文件默认使用 UTF-8 编码

本版本现在遵循 Java 及更高版本中使用的标准机制,该机制假定资源包文件使用 UTF-8 编码。

以前版本的 Keycloak 支持在第一行使用注释指定编码,例如 `# encoding: UTF-8`,该注释不再受支持,并将被忽略。

主题的消息属性文件现在使用 UTF-8 编码进行读取,并自动回退到 ISO-8859-1 编码。如果您使用的是其他编码,请将文件转换为 UTF-8。

realm 和客户端角色映射器映射的声明的值格式的更改

在本版本之前,realm(`用户 realm 角色`)和客户端(`用户客户端角色`)协议映射器在禁用 `Multivalued` 设置时映射一个字符串化的 JSON 数组。

但是,`Multivalued` 设置指示声明应该是作为列表映射,还是在禁用时,只映射来自同一列表的单个值。

在本版本中,当角色和客户端映射器被标记为单值(禁用 `Multivalued`)时,它们现在会映射到用户有效角色中的单个值。

登录 UI 中密码字段的更改

在本版本中,我们希望引入一个切换按钮来隐藏/显示密码输入。

受影响的页面
  • login.ftl

  • login-password.ftl

  • login-update-password.ftl

  • register.ftl

  • register-user-profile.ftl

通常,所有 `<input type="password" name="password" />` 现在都被封装在一个 div 中。输入元素后面跟着一个按钮,该按钮切换密码输入的可见性。

旧的代码示例

<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>

新的代码示例

<div class="${properties.kcInputGroup!}">
    <input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
    <button class="pf-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
            aria-controls="password" data-password-toggle
            data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
        <i class="fa fa-eye" aria-hidden="true"></i>
    </button>
</div>

默认 Keycloak CR 主机名

在 OpenShift 上运行时,如果启用了 ingress 并且 spec.ingress.classname 设置为 openshift-default,则可以在 Keycloak CR 中不填充 spec.hostname.hostname。operator 会将默认主机名分配给 CR 的存储版本,类似于 OpenShift Route 在没有显式主机时创建的主机名 - 也就是 ingress-namespace.appsDomain。如果 appsDomain 发生变化,或者您出于任何原因需要不同的主机名,请更新 Keycloak CR。

已弃用的 `auto-build` CLI 选项已删除

`auto-build` CLI 选项已被标记为已弃用很长时间。在本版本中,它已被完全删除,不再受支持。

执行 `start` 命令时,服务器将根据配置自动构建。为了防止这种行为,请设置 `--optimized` 标志。

kc.sh 和 shell 元字符

kc.sh 不再对参数和环境变量 JAVA_OPTS_APPEND 和 JAVA_ADD_OPENS 使用额外的 shell eval,因此继续使用双重转义/引号会导致参数被误解。例如,而不是

bin/kc.sh start --db postgres --db-username keycloak --db-url "\"jdbc:postgresql://127.0.0.1:5432/keycloak?ssl=false&connectTimeout=30\"" --db-password keycloak --hostname localhost

使用单一转义

bin/kc.sh start --db postgres --db-username keycloak --db-url "jdbc:postgresql://127.0.0.1:5432/keycloak?ssl=false&connectTimeout=30" --db-password keycloak --hostname localhost

此更改还意味着您不能使用所有参数的单引号值来调用 kc.sh。例如,您不再可以使用

bin/kc.sh "start --help"

它必须改为单独的参数

bin/kc.sh start --help

类似地,而不是

bin/kc.sh build "--db postgres"

它必须改为单独的参数

bin/kc.sh build --db postgres

在 Dockerfile run 命令中也需要使用单独的参数。

删除 RegistrationProfile 表单操作

表单操作 `RegistrationProfile`(在身份验证流的 UI 中显示为 `配置文件验证`)已从代码库中删除,也从所有身份验证流中删除。默认情况下,它位于每个 realm 的内置注册流中。用户属性的验证以及包括所有用户属性的用户创建由 `RegistrationUserCreation` 表单操作处理,因此 `RegistrationProfile` 不再需要。通常,与此更改相关的操作不需要进一步的步骤,除非您在自己的提供者中使用了 `RegistrationProfile` 类。

来自数据提供者和模型的已弃用方法

  • `RealmModel#getTopLevelGroupsStream()` 和重载方法现在已弃用

`GroupProvider` 更改

添加了一个新方法,允许搜索和分页顶级组。如果您实现了此接口,则需要实现以下方法

Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm,
                                           String search,
                                           Boolean exact,
                                           Integer firstResult,
                                           Integer maxResults)

`GroupRepresentation` 更改

  • 添加了新字段 `subGroupCount`,用于通知客户端任何给定组上有多少个子组

  • `subGroups` 列表现在只在请求层次结构数据的查询中填充

  • 此字段是从“自下而上”填充的,因此不能依赖于获取组的所有子组。使用 `GroupProvider` 或从 `GET {keycloak 服务器}/realms/{realm}/groups/{group_id}/children` 请求子组

组管理员 API 的新端点

端点 `GET {keycloak 服务器}/realms/{realm}/groups/{group_id}/children` 添加为一种获取支持分页的特定组的子组的方法

RESTEeasy Reactive

不再可以选择依赖 RESTEasy Classic,因为它不再可用。SPI 和依赖 RESTEasy Classic 以及 `org.jboss.resteasy.spi.*` 包的相关代码将需要进行迁移。

部分导出需要 manage-realm 权限

端点 `POST {keycloak 服务器}/realms/{realm}/partial-export` 和管理控制台中的相应操作现在需要 `manage-realm` 权限才能执行,而不是 `view-realm`。此端点将 realm 配置导出到 JSON 文件中,新的权限更合适。参数 `exportGroupsAndRoles` 和 `exportClients` 分别将 realm 组/角色和客户端包含在导出中,它们继续管理相同的权限(`query-groups` 和 `view-clients`)。

删除修剪事件详细信息长度的选项

从本版本开始,Keycloak 支持 `EventEntity` 详细信息列的较长值。因此,它不再支持修剪事件详细信息长度的选项 `--spi-events-store-jpa-max-detail-length` 和 `--spi-events-store-jpa-max-field-length`。

用户配置文件更新

本版本包含许多与用户配置文件相关的修复和更新,因为我们正在努力将此功能从预览版提升到正式支持的版本。SPI 中存在一些细微更改,例如 `UserProfileProvider` 接口中新增的方法 `boolean isEnabled(RealmModel realm)`。此外,一些用户配置文件类和一些验证器相关类(但不包括内置验证器实现)已从 `keycloak-server-spi-private` 模块移至 `keycloak-server-spi` 模块。但是,java 类的包保持不变。您可能会在一些极端情况下受到影响,例如当您使用自己的 `UserProfileProvider` 实现覆盖内置实现时。但是,请注意 `UserProfileProvider` 是不受支持的 SPI。

删除 Map Store

Map Store 在以前版本中是一个实验性功能。从本版本开始,它已被删除,用户应继续使用当前的 JPA 存储。

从本次发布开始,不再支持使用与--storage相关的 CLI 选项。keycloak-model-map*模块已被移除。

从翻译中移除命名空间

所有翻译都被迁移到管理控制台的一个文件中。如果您已经创建了自己的翻译或扩展了管理控制台,则需要将它们迁移到此新格式。此外,如果您在数据库中有“覆盖”,则需要从键中删除命名空间。一些键仅在不同的命名空间中相同,这最有助于理解。在这些情况下,我们在键后添加了Help后缀。

如果您愿意,可以使用此 Node 脚本帮助迁移。它将获取所有单个文件并将其放入一个新文件中,并处理一些映射。

import { readFileSync, writeFileSync, appendFileSync } from "node:fs";

const ns = [
  "common",
  "common-help",
  "dashboard",
  "clients",
  "clients-help",
  "client-scopes",
  "client-scopes-help",
  "groups",
  "realm",
  "roles",
  "users",
  "users-help",
  "sessions",
  "events",
  "realm-settings",
  "realm-settings-help",
  "authentication",
  "authentication-help",
  "user-federation",
  "user-federation-help",
  "identity-providers",
  "identity-providers-help",
  "dynamic",
];

const map = new Map();
const dup = [];

ns.forEach((n) => {
  const rawData = readFileSync(n + ".json");
  const translation = JSON.parse(rawData);
  Object.entries(translation).map((e) => {
    const name = e[0];
    const value = e[1];
    if (map.has(name) && map.get(name) !== value) {
      if (n.includes("help")) {
        map.set(name + "Help", value);
      } else {
        map.set(name, value);
        dup.push({
          name: name,
          value: map.get(name),
          dup: { ns: n, value: value },
        });
      }
    } else {
      map.set(name, value);
    }
  });
});

writeFileSync(
  "translation.json",
  JSON.stringify(Object.fromEntries(map.entries()), undefined, 2),
);

const mapping = [
  ["common:clientScope", "clientScopeType"],
  ["identity-providers:createSuccess", "createIdentityProviderSuccess"],
  ["identity-providers:createError", "createIdentityProviderError"],
  ["clients:createError", "createClientError"],
  ["clients:createSuccess", "createClientSuccess"],
  ["user-federation:createSuccess", "createUserProviderSuccess"],
  ["user-federation:createError", "createUserProviderError"],
  ["authentication-help:name", "flowNameHelp"],
  ["authentication-help:description", "flowDescriptionHelp"],
  ["clientScopes:noRoles", "noRoles-clientScope"],
  ["clientScopes:noRolesInstructions", "noRolesInstructions-clientScope"],
  ["users:noRoles", "noRoles-user"],
  ["users:noRolesInstructions", "noRolesInstructions-user"],
  ["clients:noRoles", "noRoles-client"],
  ["clients:noRolesInstructions", "noRolesInstructions-client"],
  ["groups:noRoles", "noRoles-group"],
  ["groups:noRolesInstructions", "noRolesInstructions-group"],
  ["roles:noRoles", "noRoles-roles"],
  ["roles:noRolesInstructions", "noRolesInstructions-roles"],
  ["realm:realmName:", "realmNameField"],
  ["client-scopes:searchFor", "searchForClientScope"],
  ["roles:searchFor", "searchForRoles"],
  ["authentication:title", "titleAuthentication"],
  ["events:title", "titleEvents"],
  ["roles:title", "titleRoles"],
  ["users:title", "titleUsers"],
  ["sessions:title", "titleSessions"],
  ["client-scopes:deleteConfirm", "deleteConfirmClientScopes"],
  ["users:deleteConfirm", "deleteConfirmUsers"],
  ["groups:deleteConfirm_one", "deleteConfirmGroup_one"],
  ["groups:deleteConfirm_other", "deleteConfirmGroup_other"],
  ["identity-providers:deleteConfirm", "deleteConfirmIdentityProvider"],
  ["realm-settings:deleteConfirm", "deleteConfirmRealmSetting"],
  ["roles:whoWillAppearLinkText", "whoWillAppearLinkTextRoles"],
  ["users:whoWillAppearLinkText", "whoWillAppearLinkTextUsers"],
  ["roles:whoWillAppearPopoverText", "whoWillAppearPopoverTextRoles"],
  ["users:whoWillAppearPopoverText", "whoWillAppearPopoverTextUsers"],
  ["client-scopes:deletedSuccess", "deletedSuccessClientScope"],
  ["identity-providers:deletedSuccess", "deletedSuccessIdentityProvider"],
  ["realm-settings:deleteSuccess", "deletedSuccessRealmSetting"],
  ["client-scopes:deleteError", "deletedErrorClientScope"],
  ["identity-providers:deleteError", "deletedErrorIdentityProvider"],
  ["realm-settings:deleteError", "deletedErrorRealmSetting"],
  ["realm-settings:saveSuccess", "realmSaveSuccess"],
  ["user-federation:saveSuccess", "userProviderSaveSuccess"],
  ["realm-settings:saveError", "realmSaveError"],
  ["user-federation:saveError", "userProviderSaveError"],
  ["realm-settings:validateName", "validateAttributeName"],
  ["identity-providers:disableConfirm", "disableConfirmIdentityProvider"],
  ["realm-settings:disableConfirm", "disableConfirmRealm"],
  ["client-scopes:updateSuccess", "updateSuccessClientScope"],
  ["client-scopes:updateError", "updateErrorClientScope"],
  ["identity-providers:updateSuccess", "updateSuccessIdentityProvider"],
  ["identity-providers:updateError", "updateErrorIdentityProvider"],
  ["user-federation:orderChangeSuccess", "orderChangeSuccessUserFed"],
  ["user-federation:orderChangeError", "orderChangeErrorUserFed"],
  ["authentication-help:alias", "authenticationAliasHelp"],
  ["authentication-help:flowType", "authenticationFlowTypeHelp"],
  ["authentication:createFlow", "authenticationCreateFlowHelp"],
  ["client-scopes-help:rolesScope", "clientScopesRolesScope"],
  ["client-scopes-help:name", "scopeNameHelp"],
  ["client-scopes-help:description", "scopeDescriptionHelp"],
  ["client-scopes-help:type", "scopeTypeHelp"],
  ["clients-help:description", "clientDescriptionHelp"],
  ["clients-help:clientType", "clientsClientTypeHelp"],
  ["clients-help:scopes", "clientsClientScopesHelp"],
  ["common:clientScope", "clientScopeTypes"],
  ["dashboard:realmName", "realmNameTitle"],
  ["common:description", "description"],
];

mapping.forEach((m) => {
  const key = m[0].split(":");
  try {
    const data = readFileSync(key[0] + ".json");
    const translation = JSON.parse(data);
    const value = translation[key[1]];
    if (value) {
      appendFileSync(
        "translation.json",
        '"' + m[1] + '": ' + JSON.stringify(value) + ',\n',
      );
    }
  } catch (error) {
    console.error("skipping namespace key: " + key);
  }
});

将此保存到您public/locale/<language>文件夹中的名为transform.mjs的文件中,然后使用以下命令运行它:

node ./transform.mjs
这可能无法完成完整的转换,但非常接近。

迁移到 22.0.4

一个用于指定电子邮件本地部分最大长度的新参数

添加了一个新参数--spi-user-profile-declarative-user-profile-max-email-local-part-length,用于设置电子邮件本地部分的最大长度,同时考虑到向后兼容性。默认值为 64。使用示例:

kc.[sh|bat] start --spi-user-profile-declarative-user-profile-max-email-local-part-length=100 ...

迁移到 22.0.2

从客户端高级设置组合中移除“永不过期”选项

现在已从客户端高级设置选项卡的所有组合中移除“永不过期”选项。此选项具有误导性,因为不同的生存期或空闲超时并非无限,而是受一般用户会话或领域值的限制。因此,此选项已被移除,取而代之的是另外两个选项:“继承自领域设置”(客户端使用一般领域超时)和“在...分钟后过期”(该值将覆盖客户端)。在内部,“永不过期”由-1表示。现在,该值在管理控制台中显示为警告,管理员无法直接设置它。

新的 LinkedIn OpenID Connect 社交提供商

针对以商业和就业为中心的平台,引入了一个名为LinkedIn OpenID Connect的新社交身份提供商。LinkedIn 最近发布了一个名为使用 OpenID Connect 使用 LinkedIn 登录的开发者新产品。该产品提供了一种新的方式来使用 OpenID Connect 认证会员,但默认的OpenID Connect v1.0身份提供商目前无法与之配合使用。为此,Keycloak 将此新身份提供商添加为新产品的特定社交提供商。

基于 OAuth 的旧 LinkedIn 方式似乎已完全从开发者门户中移除。目前尚不清楚现有 LinkedIn 社交提供商如何与当前应用程序配合使用。Keycloak 保留了旧提供商,并将其重命名为LinkedIn(已弃用),但它处于一个名为linkedin-oauth的已弃用功能中,该功能默认情况下处于禁用状态。它将在未来的版本中移除。如果需要,请在启动时重新启用它。

kc.[sh|bat] start --features linkedin-oauth ...

迁移到 22.0.0

从 Java EE 迁移到 Jakarta EE

Keycloak 已将其代码库从 Java EE(企业版)迁移到其继任者 Jakarta EE,这给 Keycloak 带来了各种变化。

我们已经升级了所有 Jakarta EE 规范,以便支持 Jakarta EE 10,例如

  • Jakarta Persistence 3.1

  • Jakarta RESTful Web Services 3.1

  • Jakarta Mail API 2.1

  • Jakarta Servlet 6.0

  • Jakarta Activation 2.1

Jakarta EE 10 提供了一种现代化、简化、轻量级的构建云原生 Java 应用程序的方法。此举带来的主要变化是将命名空间从javax.*更改为jakarta.*。它不适用于直接在 JDK 中提供的javax.*包,例如javax.securityjavax.netjavax.crypto等。

这些变化可能会影响您的自定义扩展、提供商或 JPA 实体。

升级到 Quarkus 3

Keycloak 升级到 Quarkus Java 框架的版本 3。Quarkus 3 继续推动 Java 开发的传统,快速发展并提供使用最新技术的尖端用户体验。它继续提高整体性能和效率。

Quarkus 3 基于 Jakarta EE 10,与 Keycloak 相同,在它们之间创建了流畅的互操作性。此外,它包含 Eclipse MicroProfile 6,与 Jakarta EE 10 Core Profile 相一致。Quarkus 3 升级的核心部分是内置对 JPA 3.1 和 Hibernate ORM 6 的支持。

quarkus.hibernate-orm.* 属性不再起作用

对于 Quarkus 3,Hibernate ORM 配置必须在persistence.xml文件中或 Quarkus 属性中指定,但不能同时在两个地方指定。Keycloak 使用persistence.xml文件,因此,不再可以通过 Quarkus 的配置属性覆盖 Keycloak 的 JPA 存储配置,这些属性用于默认持久化单元,其名称以quarkus.hibernate-orm开头。

升级到 Hibernate ORM 6

Keycloak 现在从升级到 Hibernate ORM 6.2 中获益,该版本包括性能改进、更好的 SQL、现代 JDK 支持以及对现代 RDBMS 功能的支持。性能改进主要影响 JDBC、HQL 翻译和 Criteria 翻译。

如果您有自定义提供商或 JPA 实体,这些变化可能会影响您。

我们建议您查看Quarkus 迁移指南Hibernate 发布说明以了解更多信息。

从 Keycloak JS 适配器中移除旧的 Promise API

旧的 Promise API 方法已从 Keycloak JS 适配器中移除。这意味着不再可能对从适配器返回的 Promise 调用.success().error()。相反,应该使用标准化的 Promise 方法,例如.then().catch()

迁移前
const keycloak = new Keycloak();

keycloak.init()
  .success(function(authenticated) {
    alert(authenticated ? 'authenticated' : 'not authenticated');
  }).error(function() {
    alert('failed to initialize');
  });
迁移后
const keycloak = new Keycloak();

keycloak.init()
  .then(function(authenticated) {
    alert(authenticated ? 'authenticated' : 'not authenticated');
  }).catch(function() {
    alert('failed to initialize');
  });
或者,当使用await关键字来解开这些 Promise 时
const keycloak = new Keycloak();

try {
  const authenticated = await keycloak.init();
  alert(authenticated ? 'authenticated' : 'not authenticated');
} catch (error) {
  alert('failed to initialize');
}

导出和导入会自动执行构建

在以前的版本中,exportimport命令需要先运行build命令。从本版本开始,exportimport命令会在构建时间配置更改时自动重新构建 Keycloak。

在迁移现有的首先运行build命令的脚本时,请在exportimport命令中添加--optimized命令行选项以避免 Keycloak 自动重新构建映像。在没有添加--optimized选项的情况下这样做,可能会导致 Keycloak 触发重新构建并恢复到默认值,然后连接到数据库进行导出和导入将不起作用。

以下示例假设运行时参数(如数据库密码)是通过配置文件或环境变量提供的。

迁移前:在运行导出命令之前运行构建命令
bin/kc.[sh|bat] build --db=postgres ...
bin/kc.[sh|bat] export --dir <dir>
迁移后:在导出命令中添加--optimized
bin/kc.[sh|bat] build --db=postgres ...
bin/kc.[sh|bat] export --optimized --dir <dir>
迁移后:利用自动构建功能
bin/kc.[sh|bat] export --dir <dir> --db=postgres ...
注意

当自动构建运行时,构建时间选项将对所有后续命令生效,这些命令使用--optimized标志启动,包括start命令。

在以前的版本中,exportimport命令只允许在配置文件或环境变量中使用运行时参数,例如数据库 URL。从本版本开始,这些运行时参数现在也可以在命令行中使用。使用--help选项可以找到有关支持参数的信息。

Keycloak 管理客户端工件已重命名

升级到 Jakarta EE 后,Keycloak 管理客户端的工件已重命名为更具描述性的名称,并考虑了长期可维护性。我们仍然提供两个独立的 Keycloak 管理客户端,一个使用 Jakarta EE,另一个使用 Java EE 支持。

我们停止发布org.keycloak:keycloak-admin-client-jakarta工件。使用 Jakarta EE 支持的 Keycloak 管理客户端的默认工件是org.keycloak:keycloak-admin-client(从版本 22.0.0 开始)。

新的具有 Java EE 支持的工件是org.keycloak:keycloak-admin-client-jee

Jakarta EE 支持
迁移前
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-admin-client-jakarta</artifactId>
    <version>21.0.0</version>
</dependency>
迁移后
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-admin-client</artifactId>
    <version>22.0.0</version>
</dependency>
Java EE 支持
迁移前
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-admin-client</artifactId>
    <version>21.0.0</version>
</dependency>
迁移后
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-admin-client-jee</artifactId>
    <version>22.0.0</version>
</dependency>

直通代理模式更改

Keycloak 的代理配置设置对于模式直通不再解析请求中的 HTTP 转发标头,因为当代理以直通模式转发 HTTPS 连接时,代理无法添加、移除或更新 HTTP 标头。

希望在客户端请求中解析 HTTP 标头的安装应使用边缘重新加密设置。

有关详细信息,请参阅使用反向代理

所有主题的一致回退消息解析

此更改仅在使用领域本地化消息时才会影响您。

在此版本之前,当使用领域本地化消息时,回退消息的解析在主题之间不一致。有关更多信息,请查看以下问题

所有主题的实现现已统一。一般来说,与最特定匹配语言标签的消息具有最高优先级。如果同时存在领域本地化消息和主题 18n 消息,则领域本地化消息具有更高的优先级。总结来说,消息的优先级如下(RL = 领域本地化,T = 主题 i18n 文件):RL <variant> > T <variant> > RL <region> > T <region> > RL <language> > T <language> > RL en > T en

可能可以用一个例子更好地解释这一点:当请求变体de-CH-1996并且存在该变体的领域本地化消息时,将使用此消息。如果不存在这样的领域本地化消息,则会在主题 i18n 文件中搜索与该变体相对应的消息。如果不存在这样的消息,则会搜索该区域(de-CH)的领域本地化消息。如果不存在这样的领域本地化消息,则会在主题 i18n 文件中搜索该区域的消息。如果仍然没有找到消息,则会搜索该语言(de)的领域本地化消息。如果不存在匹配的领域本地化消息,则会在主题 i18n 文件中搜索该语言的消息。作为最后的回退,将使用英语(en)翻译:首先,将搜索英语领域本地化 - 如果未找到,则会在主题 18n 文件中搜索英语消息。

UserQueryProvider 更改

UserQueryProvider 接口被拆分为两个。一个是UserQueryMethodsProvider,它提供查询用户的功能。第二个是UserCountMethodsProvider,它提供在特定存储中统计用户数量的功能。

Keycloak 现在能够区分能够有效执行计数查询的用户存储提供程序和那些无法执行计数查询的用户存储提供程序。UserQueryProvider 接口仍然存在,并且扩展了两个新接口。因此,现有的 UserQueryProvider 实现无需任何修改,因为它保留了相同的方法。

LDAPStorageProvider 搜索更改

从本版本开始,Keycloak 在查询联合 LDAP 数据库时使用分页机制。搜索用户应该与在本地数据库中搜索一致。

从本版本开始,LDAPStorageProvider 只实现了UserQueryMethodsProvider,而不是UserQueryProvider

弃用 Keycloak OpenID Connect 适配器

从本版本开始,我们不再投入时间到以下 Keycloak OpenID Connect 适配器

  • Keycloak Wildfly OpenID Connect 适配器

  • Keycloak JEE Servlet OpenID Connect 适配器

  • Keycloak Spring Boot 和 Spring Security OpenID Connect 适配器

此举已反映在我们的文档和快速入门存储库中。请考虑查看以下参考资料以获取更多信息

我们建议您开始考虑将应用程序迁移到上述参考资料中的替代方案。这些适配器在将来的版本中将不再可用。

弃用 Keycloak JEE SAML 适配器

Keycloak JEE SAML 适配器已停止使用,在本版本发布后,我们将不再投入时间开发它。

官方适配器现在基于 Jakarta,并且应该在您将应用程序切换到此技术后立即使用。

此更改已反映在我们的文档和快速入门存储库中。有关更多信息,请考虑查看以下参考资料

如果您无法将应用程序迁移到 Jakarta,您仍然可以使用“传统”SAML JEE 适配器,并且仍然能够与服务器的将来版本集成。但是,请考虑尽快升级您的应用程序,因为我们不再提供对 JEE 的支持。

openshift-integration 功能的更改

预览功能openshift-integration已从 Keycloak 代码库中删除,并移动到单独的扩展程序中。这包括移动相关的提供程序,例如用于 Openshift 集成的自定义客户端存储提供程序和令牌审查端点。

如果您使用此功能,则启动 Keycloak 服务器时不应再使用openshift-integration 功能,而是需要部署来自自定义扩展程序的 JAR 文件。您可以查看Openshift 扩展程序及其 README 文件中的说明,了解如何将扩展程序部署到您的 Keycloak 服务器。

Openshift 扩展程序不受 Keycloak 团队官方支持和维护。您仅在您自己的风险下使用它。
删除 Http Challenge 流程

内置身份验证流程http challenge以及身份验证器实现no-cookie-redirectbasic-authbasic-auth-otp已被删除。http challenge 身份验证流程也旨在用于 Openshift 集成,因此它已与上述其他相关功能一起删除。身份验证器实现已移至上一段中描述的 Openshift 扩展程序。

如果您将http challenge 流程用作领域流程或作为First Broker LoginPost Broker Login流程用于任何身份提供者,则迁移将不可行。请确保在迁移之前更新您的领域配置以消除对http challenge 流程的使用。如果您将http challenge 流程用作Authentication Flow Binding Override用于任何客户端,则迁移将完成,但您将无法再登录到该客户端。迁移后,您需要重新创建流程并更新客户端配置以使用新的/不同的Json 流程。

删除第三方依赖项

删除 openshift-integration 使我们能够从 Keycloak 分发版中删除一些第三方依赖项。这包括openshift-rest-clientokio-jvmokhttpcommons-langcommons-compressjboss-dmrkotlin-stdlib。这意味着,如果您使用这些库中的任何一个作为您部署到 Keycloak 服务器的自定义提供程序的依赖项,您可能还需要将这些jar 文件明确复制到 Keycloak 分发版的providers 目录中。

不再对 JAX-RS 资源启用上下文和依赖项注入

为了提供更好的运行时并尽可能利用底层堆栈,所有使用javax.ws.rs.core.Context 注解的上下文数据注入点都被删除了。性能方面的预期改进包括不再在请求生命周期中多次创建代理实例,以及大幅减少运行时的反射代码量。

如果您扩展了以下 SPI 中的任何一个

  • PolicySpi

  • AdminRealmResourceSpi

  • IdentityProviderSpi

  • RealmResourceSPI

您应该查看您的自定义 JAX-RS(子)资源,以便按照以下方式获取任何上下文数据

KeycloakSession session = org.keycloak.common.util.Resteasy.getContextData(KeycloakSession.class);

如果您需要访问当前请求和响应对象,您现在可以直接从KeycloakSession 获取它们的实例

@Context
org.jboss.resteasy.spi.HttpRequest request;
@Context
org.jboss.resteasy.spi.HttpResponse response;

被替换为

KeycloakSession session = // obtain the session, which is usually available when creating a custom provider from a factory
KeycloakContext context = session.getContext();

HttpRequest request = context.getHttpRequest();
HttpResponse response = context.getHttpResponse();

如果您在调用 JAX-RS 资源方法时无法访问KeycloakSession 实例,您可以从 JAX-RS 运行时获取上下文数据,如下所示

KeycloakSession session = org.keycloak.common.util.Resteasy.getContextData(KeycloakSession.class);

可以通过KeycloakContext 实例从运行时获取其他上下文数据

KeycloakSession session = // obtain the session
KeycloakContext context = session.getContext();
MyContextualObject myContextualObject = context.getContextObject(MyContextualObject.class);

升级您的自定义 JAX-RS 资源

如果您通过以下 SPI 扩展服务器的 REST API

  • PolicySpi

  • AdminRealmResourceSpi

  • IdentityProviderSpi

  • RealmResourceSPI

您需要将一个名为beans.xml 的空文件添加到打包自定义提供程序的 JAR 文件中。否则,运行时服务器无法识别它们。

如果您使用的是RealmResourceSPIAdminRealmResourceSpi,您可以在META-INF 下添加一个名为beans.xml 的空文件,或者使用jakarta.ws.rs.ext.Provider 注解注释 JAX-RS 资源类。

您还应该确保您的 JAX-RS 方法分别通过@Consumes@Produces 注解声明输入和输出的预期媒体类型。

数据提供程序和模型中的弃用方法

在 Keycloak 的早期版本中,提供程序和模型接口经过清理过程,其中涉及弃用某些方法。在本版本中,这些方法已被删除,并且一些其他方法已被弃用。Keycloak 21 中这些方法的 Javadoc 包含有关其对应替换的信息。

  • RealmModel#searchForGroupByNameStream(String, Integer, Integer) 已被删除。

  • UserProvider#getUsersStream(RealmModel, boolean) 已被删除。

  • UserSessionPersisterProvider#loadUserSessions(int, int, boolean, int, String) 已被删除。

  • 为 Streamification 工作添加的接口已被删除。例如,RoleMapperModel.Streams 及类似的接口。

  • 联合存储提供程序类中的Streams 接口已弃用。

  • KeycloakModelUtils#getClientScopeMappings 已被删除。

  • KeycloakSession 中的弃用方法已被删除。

  • UserQueryProvider#getUsersStream 方法已被删除。

多个 Keycloak 实例

可以在同一个命名空间中创建多个 Keycloak CR,并且将由操作员独立管理。为了允许这样做,必须重新创建由操作员的旧版本创建的 StatefulSets。这将在升级操作员时自动发生,并导致少量停机时间。

k8s.keycloak.org/v2alpha1 更改

条件状态字段已从布尔值更改为字符串,以符合标准 Kubernetes 条件。在 CRD 中,它将暂时表示为接受任何内容,但它将始终是一个字符串。请确保您对该字段的任何使用都更新为期望值“True”、“False”或“Unknown”,而不是 true 或 false。

Keycloak 支持 IPv4/IPv6 双栈

Keycloak 支持 IPv4/IPv6 双栈,并且默认情况下可以通过 IPv4 和 IPv6 地址访问。在 Keycloak 的旧版本中,默认方法是仅使用 IPv4 地址。

有关更多详细信息,请参阅使用 IPv4 或 IPv6 配置 Keycloak 服务器

迁移到 21.1.0

类路径上默认提供 Javascript 引擎

在之前的版本中,当 Keycloak 在 Java 17 上与 Javascript 提供程序(脚本身份验证器、Javascript 授权策略或 OIDC 和 SAML 客户端的脚本协议映射器)一起使用时,需要将 javascript 引擎复制到分发版中。现在不再需要这样做,因为 Nashorn javascript 引擎默认情况下在 Keycloak 服务器中可用。当您部署脚本提供程序时,建议不要将 nashorn 脚本引擎及其依赖项复制到 Keycloak 分发版中。

服务帐户客户端的默认 Client ID 映射器的更改

服务账户客户端 的默认 客户端 ID 映射器已更改。令牌声明名称 字段值已从 clientId 更改为 client_idclient_id 声明符合 OAuth2 规范。

clientId 用户会话注释仍然存在。

Keycloak JS 适配器必须使用 new 运算符实例化

从历史上看,可以通过直接调用 Keycloak() 函数来创建 Keycloak JS 适配器的实例

const keycloak = Keycloak();

为了使之与 JavaScript 世界中的现代约定保持一致,可以使用 new 运算符 来创建实例

const keycloak = new Keycloak();

函数式构造函数已被弃用了一段时间,但从本版本开始,我们将在使用它时主动记录弃用消息。这种构造函数将在未来版本中删除,因此请确保将您的代码迁移为使用 new 运算符。

迁移到 21.0.2

条款和条件用户属性迁移

terms_and_conditions 用户属性在 21.0.0 中意外更改为大写。此版本将用户属性还原为小写。在接受条款和条件页面时会设置属性的值。

如果您的任何自定义扩展依赖于此属性,您可能需要调整您的代码以检查 terms_and_conditionsTERMS_AND_CONDITIONS 两个属性。

迁移到 21.0.0

Keycloak 使用 Micrometer 进行指标

Keycloak 提供了一个可选的指标端点,该端点以 Prometheus 格式导出指标。在本版本中,提供此数据的实现从 SmallRye 切换到 Micrometer,它是 Quarkus 推荐的指标库

由于此更改,指标已重命名。下表显示了一些示例。

在升级之前,建议在更改之前和之后审查从端点返回的所有指标,并更新其在仪表板和警报中的使用情况。

表 1. 更改的指标名称示例
旧指标名称 新指标名称

base_gc_total

jvm_gc_pause_seconds_count

base_gc_time_total_seconds

jvm_gc_pause_seconds_sum

base_thread_count

jvm_threads_live_threads

vendor_agroal_*

agroal_*

弃用的 RSA_SHA1 和 DSA_SHA1 算法用于 SAML

算法 RSA_SHA1DSA_SHA1 可配置为 SAML 适配器、客户端和身份提供者上的 签名算法,现已弃用。我们建议使用基于 SHA256SHA512 的更安全的替代方案。此外,使用这些算法验证签名 SAML 文档或断言在 Java 17 或更高版本上不起作用。如果您使用此算法,并且使用您的 SAML 文档的另一方在 Java 17 或更高版本上运行,则验证签名将不起作用。

可能的解决方法是从文件 $JAVA_HOME/conf/security/java.security 中的属性 jdk.xml.dsig.secureValidationPolicy 配置的“不允许的算法”列表中删除诸如 http://www.w3.org/2000/09/xmldsig#rsa-sha1http://www.w3.org/2000/09/xmldsig#dsa-sha1 之类的算法。

SAML SP 元数据更改

在本版本中,Keycloak 将拒绝解密使用为签名目的生成的 realm 密钥加密的断言。此更改意味着从 IDP 到 SP(Keycloak 充当 SP)的所有加密通信将停止工作。

有两种方法可以使此方法起作用

  • 要么使用更新版本的 Keycloak 生成的元数据更新 IDP 配置,

  • 要么在向后兼容模式下运行 Keycloak,这将使 Keycloak 与旧版 Keycloak 版本生成的元数据一起使用。可以使用 -Dkeycloak.saml.deprecated.encryption=true 标志启用此模式。请注意,此向后兼容模式计划在 Keycloak 24 中删除。

来自用户会话提供者的弃用方法已删除

在 Keycloak 13 中引入了 UserLoginFailureProvider,并且 UserSessionProvider 中的一些方法已移至那里。UserSessionProvider 中的方法已弃用,现在已删除。这些方法的 Javadoc 包含相应的替代方法(请参阅 Keycloak 20 版本的 Javadoc)。

使用旧版管理控制台的自定义主题将不起作用

旧版管理控制台在以前的版本中已弃用,现在已最终删除。这也意味着使用它作为父主题或从它导入的自定义主题将不起作用。强烈建议不要部署此类主题,因为扩展旧版管理控制台不再适用,并且 Keycloak 中可能存在此类已部署主题的问题(至少在日志中存在警告或错误)。

Curl 已从容器中删除

已修改 Keycloak 容器映像 以增强安全性。因此,curl 和其他 CLI 工具已被删除,您可能已在您的自定义映像中使用过它们。有关如何处理此更改的信息,请参阅更新后的 容器指南

迁移到 20.0.0

RESTEasy 版本更新

将 Keycloak 管理 REST 客户端的 RESTEasy 版本更新到下一个主要版本。

H2 版本更新

Keycloak 随 H2 数据库驱动程序一起用于开发目的。由于它仅用于开发目的,因此绝不应在生产环境中使用。

在本版本中,H2 驱动程序已从 1.x 版本升级到 2.x 版本。此更改可能需要更改现有 Keycloak 设置中的 H2 JDBC URL 或迁移 H2 数据库文件。

H2 JDBC URL 的更改

为了使 Keycloak 能够使用其 JPA 传统存储与 H2 2.x 版本一起运行,JDBC URL 需要属性 NON_KEYWORDS=VALUE

在 Keycloak 初始化 H2 且没有额外参数的设置中,Keycloak 将自动追加该属性。这是开发设置的默认设置。

如果在命令行或配置文件中提供 H2 JDBC URL,并且它已经在 JDBC URL 中包含 NON_KEYWORDS= 属性,则需要使用 VALUE 关键字修改此属性。

如果在 Keycloak 之外初始化 H2 数据库的连接工厂,则该初始化需要负责添加 NON_KEYWORDS 属性。

有关详细信息,请参阅 H2 文档 关于 NON_KEYWORDS 属性的内容

H2 数据库文件的升级

使用 H2 1.x 版本创建的 H2 数据库基本文件不应与 2.x 版本一起使用。

清除现有的 H2 数据库文件以从空数据库开始,使用 Keycloak 的导出和导入功能导出和导入 realm,或者参考 H2 数据库项目网站上的迁移说明,了解有关如何迁移 H2 数据库内容的详细信息。

新版 Keycloak 运算符中的重大更改

为了使用最新版本的 Keycloak 运算符,需要手动重新安装和升级您的 CR。没有自动迁移。

此版本包含 Keycloak CR 中的以下重大更改

serverConfiguration 自由格式字段已重命名

从现在开始,它被称为 additionalOptions。此决定的想法是使其与 Keycloak Quarkus 分发更加一致,并实现/保持命名一致性。serverConfiguration 仍可用于配置 Keycloak 自定义资源 (CR) 中未声明替代方案的选项。服务提供者是一个很好的使用示例。

入口选项已细化

过去,它通常通过 disableDefaultIngress 属性定义。我们决定对其进行一些澄清,因此从现在开始,您可以使用以下结构来控制您的入口设置

spec:
    ...
    ingress:
      enabled: false
添加了 HTTP 选项

与入口类似,您也可以以更好的结构方式定义多个 HTTP 选项

spec:
    ...
  http:
    httpEnabled: true
    httpPort: 80
    httpsPort: 443
    tlsSecret: my-tls-secret
添加了主机名选项

最后但同样重要的是,主机名选项也已更改

spec:
    ...
  hostname:
    hostname: [keycloak-server-hostname]
    admin: [admin-console-hostname]
    adminUrl: [admin-console-base-url]
    strict: [true|false]
    strictBackchannel: [true|false]
某些字段不再是必需的

hostnametlsSecret 字段现在是可选的,以与 Quarkus 分发配置保持一致。因此,我们还删除了将 INSECURE-DISABLE 特殊值设置为这些字段的可能性。为了禁用主机名检查并启用 HTTP,请遵循与 Quarkus 分发相同的方法,即设置 strict: falsestrictBackchannel: falsehttpEnabled: true 字段。

OLM 通道已更改为快速

Keycloak 运算符生命周期管理器的默认通道已更改为 fast

来自数据提供者和模型的弃用方法已删除

在 Keycloak 15 之前,我们对提供者和模型接口进行了清理,在此过程中弃用了一些方法。这些方法的 Javadoc 包含相应的替换方法(请参阅 Keycloak 19 版本的 Javadoc)。在本版本中,这些方法已被删除。以下是所有已更改类的列表。

弃用和删除方法最常见的模式如下。

  • 流化 - 接口现在仅包含基于流的方法。

    例如,在 GroupProvider 接口中

    @Deprecated
    List<GroupModel> getGroups(RealmModel realm);

    被替换为

    Stream<GroupModel> getGroupsStream(RealmModel realm);

    有关流化的更多详细信息,请参阅 KEYCLOAK-14011

  • 一致的参数顺序 - 方法现在具有严格的参数顺序,其中 RealmModel 始终是第一个参数。

    例如,在 UserLookupProvider 接口中

    @Deprecated
    UserModel getUserById(String id, RealmModel realm);

    被替换为

    UserModel getUserById(RealmModel realm, String id)
已更改接口的列表

(o.k. 代表 org.keycloak. 包)

  • server-spi 模块

    • o.k.credential.CredentialInputUpdater

    • o.k.credential.UserCredentialStore

    • o.k.models.ClientProvider

    • o.k.models.ClientSessionContext

    • o.k.models.GroupModel

    • o.k.models.GroupProvider

    • o.k.models.KeyManager

    • o.k.models.KeycloakSessionFactory

    • o.k.models.ProtocolMapperContainerModel

    • o.k.models.RealmModel

    • o.k.models.RealmProvider

    • o.k.models.RoleContainerModel

    • o.k.models.RoleMapperModel

    • o.k.models.RoleModel

    • o.k.models.RoleProvider

    • o.k.models.ScopeContainerModel

    • o.k.models.UserCredentialManager

    • o.k.models.UserModel

    • o.k.models.UserProvider

    • o.k.models.UserSessionProvider

    • o.k.models.utils.RoleUtils

    • o.k.sessions.AuthenticationSessionProvider

    • o.k.storage.client.ClientLookupProvider

    • o.k.storage.group.GroupLookupProvider

    • o.k.storage.user.UserLookupProvider

    • o.k.storage.user.UserQueryProvider

  • server-spi-private 模块

    • o.k.events.EventQuery

    • o.k.events.admin.AdminEventQuery

    • o.k.keys.KeyProvider

所有更改都与以下问题相关联:问题

迁移到 19.0.2

OpenID Connect 注销提示

在 Keycloak 18.0.0 中,注销现在与新的 OIDC 规范兼容,该规范更改了 url 参数的处理方式。但是,为了也与早期版本保持兼容,引入了兼容性标志。有关向后兼容选项的更多信息,请参阅升级指南,该选项允许您的应用程序继续使用旧格式的 url 参数。

虽然 url 参数现在可以配置为兼容,但与 keycloak 17 及更早版本仍然存在一个不兼容之处。如果用户未提供有效的 idTokenHint,则会显示注销提示,而不是成功注销重定向。因此,引入了一个新的兼容性标志 suppress-logout-confirmation-screen 来抑制注销屏幕。

您可以在启动服务器时启用此参数,方法是输入以下命令

bin/kc.[sh|bat] --spi-login-protocol-openid-connect-suppress-logout-confirmation-screen=true start

使用此配置,您仍然可以使用注销端点,而无需用户提示。

向后兼容开关将在未来的某个版本(可能是 Keycloak 23)中删除。建议您尽快按照上述说明更新您的客户端,而不是依赖此开关。

通过 SAML javascript 协议映射器部署脚本

到目前为止,在他们的 SAML 客户端或客户端范围使用 SAML javascript 协议映射器的管理员可以通过 Keycloak 管理控制台以及通过 RESTful 管理 API 将脚本上传到服务器。

从现在开始,此功能已禁用,用户应直接将脚本部署到服务器。此行为与其他基于脚本的提供程序保持一致。有关更多详细信息,请查看JavaScript 提供程序

用户信息端点更改

错误响应更改

用户信息端点现在返回完全符合RFC 6750(OAuth 2.0 授权框架:承载令牌使用)的错误响应。错误代码和描述(如果可用)作为 WWW-Authenticate 挑战属性提供,而不是 JSON 对象字段。响应将根据错误条件进行如下操作:

  • 如果未提供访问令牌

    401 Unauthorized
    WWW-Authenticate: Bearer realm="myrealm"
  • 如果同时使用多种方法提供访问令牌(例如,授权标头 + POST access_token 参数),或 POST 参数重复

    400 Bad Request
    WWW-Authenticate: Bearer realm="myrealm", error="invalid_request", error_description="..."
  • 如果访问令牌缺少 openid 范围

    403 Forbidden
    WWW-Authenticate: Bearer realm="myrealm", error="insufficient_scope", error_description="Missing openid scope"
  • 如果无法解析用于用户信息响应签名/加密的加密密钥

    500 Internal Server Error
  • 如果出现令牌验证错误,则会返回 401 Unauthorized,并结合使用 invalid_token 错误代码。此错误包括用户和客户端相关检查,实际上涵盖了所有剩余的错误情况

    401 Unauthorized
    WWW-Authenticate: Bearer realm="myrealm", error="invalid_token", error_description="..."
其他更改
  • 现在要求访问令牌具有 openid 范围,这是 UserInfo 作为 OpenID Connect 特定功能而不是 OAuth 2.0 的规定。如果令牌中缺少 openid 范围,则请求将被拒绝,并返回 403 Forbidden(见上文)。

  • 用户信息现在检查用户状态,如果用户被禁用,则返回 invalid_token 响应。

迁移到 19.0.0

新管理控制台现在是默认控制台

新管理控制台现在是 Keycloak 中的默认控制台。如果您无法开始使用新管理控制台,则可以通过禁用新控制台来继续使用旧管理控制台,例如,运行

bin/kc.sh start-dev --features-disabled=admin2

继续使用旧管理控制台的另一种方法是将主 realm 或任何其他 realm 的主题设置为 keycloak

由于新管理控制台与旧管理控制台有很大不同,现在基于 React 并使用更新版本的 PatternFly,任何自定义主题很可能需要从头开始重新实现。要为新管理控制台创建自定义主题,该主题应扩展 keycloak.v2 而不是 keycloak

如果您已明确将主 realm 或任何其他 realm 的管理控制台主题设置为 keycloak,它将继续使用旧管理控制台。要更新到新管理控制台,您需要将主题更改为 keycloak.v2

旧管理控制台将在 Keycloak 21 中删除。

对服务器配置和启动的更改

在此版本之前,您会在运行 start 命令时使用 --auto-build 来告诉服务器有条件地运行 build,如果在启动服务器之前有任何构建选项已更改。

在此版本中,--auto-build 标志已弃用,您不再需要使用它来指示您要在启动服务器时设置构建选项。相反,如果任何构建选项已更改,服务器始终会在启动服务器之前默认运行 build。新行为通过使运行 build 命令之前变得可选(尽管强烈建议)来改善配置和启动服务器时的整体体验,以便获得最佳的启动时间和内存占用量。

现在,为了获得最佳的启动时间和内存占用量,请设置 --optimized 选项以禁用新的默认行为。--optimized 标志告诉服务器在启动时不需要直接检查并运行 build

kc.sh start --optimized

如果您已经在使用自定义映像来设置构建选项并运行优化的 Keycloak 容器,请确保在调用 start 命令时设置 --optimized 选项。

有关更多详细信息,请查看配置指南容器指南

对健康端点的潜在破坏性更改

在 Keycloak 19.0.0 之前,基于 quarkus 的 Keycloak 发行版始终无意中启用了以下非应用程序端点

  • /q/health

  • /q/health/live

  • /q/health/ready

  • /q/metrics

从 Keycloak 19.0.0 开始,这些端点已禁用,请求将导致 404 HTTP 状态代码。如果您正在使用 /q/…​ 端点,请确保在升级到 Keycloak 19.0.0 时更改您的探测和监控系统,以使用预期的健康端点。

预期的健康端点是

  • /health

  • /health/live

  • /health/ready

  • /metrics

除了禁用 /q/ 端点外,还对健康端点进行了以下改进

  • 用于存活探测的 health/live 端点现在与数据库连接健康状况分离,以符合当前的最佳实践,并且不会与 health/ready 端点具有相同的行为。因此,当调用 /health/live 时,数据库检查不再显示在 checks: 数组中,因此,当发生数据库故障时,存活探测仍将返回 HTTP 状态代码 200 和状态 UP,因此不会触发任何 Pod 重启。

  • 用于就绪探测的 health/ready 端点仍然检查数据库连接是否正常工作。请确保您不仅在配置中设置了 health-enabled=true,还设置了 metrics-enabled=true,以启用数据库检查,从而实现有效的就绪探测。当数据库连接处于不健康状态时,它将返回 HTTP 状态代码 503 和状态 DOWN。

预计未来会在该领域进行更多改进。有关更多信息,请参阅健康指南

使用 GELF/集中式日志管理的更改

如发行说明中所述,Keycloak 现在开箱即用地支持 gelf 日志记录,用于集中式日志记录系统。

如果您在先前版本中自己添加了 gelf 相关的 quarkus jar,请确保切换到日志记录指南中支持的配置选项,并将您的 jar 从 providers 文件夹中删除。

影响开发人员的更改

Keycloak 正在进行大规模重构,这会影响现有代码。其中一些更改需要更新现有代码。这些将在下面更详细地描述。

更改的理由

Keycloak 存在一些局限性;例如,升级 Keycloak 集群需要停机。为了解决这些局限性,已启动了深入的重构。

此版本中的更改主要与存储重构和新存储的准备工作有关,称为地图存储。此存储最终将替换当前存储,该存储将在此版本中称为传统存储。传统存储将在 Keycloak 中保持可用几个版本。

新的存储在服务层和存储层之间实施了严格的职责分离。因此,服务层对对象来源的可见性将受到限制,因此它将无法区分缓存或未缓存的对象,或来自本地或联合存储的对象。

用户存储 SPI 将被弃用。它将在未来几个版本中得到支持,但最终将被地图存储 SPI 替换,该 SPI 将提供为任何已识别区域(例如用户、角色、客户端或组)创建自定义存储的能力。

依赖于传统存储中服务可用的详细程度的扩展将需要进行调整,以在传统存储的整个弃用期间保留此功能。下一部分将描述如何完成此调整。

使用旧存储和映射存储是互斥的;一个存储不能在另一个处于活动状态时使用。

模块结构的更改

作为引入新的存储功能的一部分,围绕KeycloakSession中存储功能的几个公共 API 已合并,并且一些已被弃用,将在下一个版本中移除。引入了三个新模块,并将来自server-spiserver-spi-privateservices模块的面向数据的代码移动到那里。

org.keycloak:keycloak-model-legacy

包含来自旧存储的所有面向公众的 API,例如用户存储 API。

org.keycloak:keycloak-model-legacy-private

包含与用户存储管理相关的私有实现,例如存储*Manager类。

org.keycloak:keycloak-model-legacy-services

包含直接在旧存储上操作的所有 REST 端点,在新存储中没有意义。

只要支持旧存储,这些模块就会可用。在那之后,它们将被移除。

此更改会影响 Wildfly 分发版中现有用户存储提供程序的部署。如果您的用户存储提供程序作为 WAR 存档部署,您需要将META-INF/jboss-deployment-structure.xml文件添加到该存档中,并说明如下所示的修改后的依赖项。

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        <dependencies>
            <module name="org.keycloak.keycloak-model-legacy" meta-inf="import"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>
KeycloakSession中的更改

KeycloakSession已简化。KeycloakSession中的几个方法已被弃用,并将将在未来版本中移除。

KeycloakSession会话包含多个方法,用于获取特定对象类型的提供程序,例如对于UserProvider,有users()userLocalStorage()userCache()userStorageManager()userFederatedStorage()。对于必须了解每个方法的确切含义的开发人员来说,这种情况可能会令人困惑,并且取决于当前的存储布局。新存储不区分联合存储和本地存储。

出于这些原因,只有users()方法将保留在KeycloakSession中,并且应该替换上面列出的所有其他调用。其他方法已被弃用,最终将被移除。相同模式的弃用适用于其他对象区域的方法,例如clients()groups()。所有以*StorageManager()*LocalStorage()结尾的方法现在都会在被调用时抛出异常,因为在新存储中没有直接替代品。下一部分描述了如何将这些调用迁移到新的 API 或在使用旧存储时使用旧 API。

KeycloakSession 中的弃用方法将在未来版本中移除。keycloak-model-legacy-*模块将可用更长时间,最终将被移除。

迁移不依赖于旧存储的现有提供程序

如果现有提供程序没有调用弃用方法,则不需要迁移,这应该是大多数提供程序的情况。

如果提供程序使用弃用方法,但并不依赖于本地存储与非本地存储,则将调用从现在已弃用的userLocalStorage()更改为方法users()是最佳选择。请注意,语义在此处发生了变化,因为新方法在本地设置中启用了缓存的情况下会包含缓存。

迁移之前:访问现在抛出异常的弃用 API
session.userLocalStorage();
迁移之后:访问新 API 调用者不依赖于旧存储 API
session.users();
迁移依赖于旧存储的现有提供程序

在自定义提供程序需要区分特定提供程序模式的罕见情况下,可以通过使用LegacyStoreManagers数据存储提供程序来访问弃用的对象。此选项只有在旧模块是部署的一部分时才可用。

迁移之前:访问现在抛出异常的弃用 API
session.userLocalStorage();
迁移之后:通过 LegacyStoreManagers API 访问旧功能
((LegacyDatastoreProvider) session.getProvider(DatastoreProvider.class)).userLocalStorage();

一些与用户存储相关的 API 已包装在org.keycloak.storage.UserStorageUtil中,以方便使用。

创建自定义存储提供程序

创建自定义存储提供程序的 API 尚未完全稳定,尽管它作为技术预览版可用。有关详细信息,请参阅MapStorageProvider SPI 及其 Javadoc。新 API 的可用性是下一个 Keycloak 版本的优先事项。

RealmModel的更改

方法getUserStorageProvidersgetUserStorageProvidersStreamgetClientStorageProvidersgetClientStorageProvidersStreamgetRoleStorageProvidersgetRoleStorageProvidersStream已被移除。依赖于这些方法并在启用旧存储的情况下运行的代码应将实例强制转换为以下形式

迁移之前:代码由于 API 更改而无法编译
realm.getClientStorageProvidersStream()...;
迁移之后:将实例强制转换为旧接口
((LegacyRealmModel) realm).getClientStorageProvidersStream()...;

类似地,以前实现RealmModel接口并希望提供这些方法的代码应实现新接口LegacyRealmModel。此接口是RealmModel的子接口,并包含旧方法。

迁移之前:代码实现旧接口
public class MyClass extends RealmModel {
    /* might not compile due to @Override annotations for methods no longer present
       in the interface RealmModel. /
    / ... */
}
迁移之后:代码实现新接口
public class MyClass extends LegacyRealmModel {
    /* ... */
}
接口UserCache已移至旧模块

由于对象的缓存状态将对服务透明,因此接口UserCache已移至模块keycloak-legacy。因此,对session.userCache()的调用将只返回一个UserProvider,这是一个重大更改。

依赖于旧实现的代码应直接访问UserCache。虽然使用旧存储的缓存时可能需要此类调用,但在使用新的映射存储时则不需要,因为新的映射存储会透明地处理缓存。

迁移之前:代码由于返回类型更改而无法编译
// session.userCache() might return null, null-check omitted for brevity.
session.userCache().evict(realm, user);
迁移之后:直接使用 API
// session.getProvider(UserCache.class) might return null, null-check omitted for brevity.
session.getProvider(UserCache.class).evict(realm, user);

要触发域的失效,请考虑触发事件,而不是使用UserCache API。

迁移之前:代码由于返回类型更改而无法编译
UserCache cache = session.getProvider(UserCache.class);
if (cache != null) cache.clear();
迁移之后:使用失效 API
session.invalidate(InvalidationHandler.ObjectType.REALM, realm.getId());
用户的凭据管理

以前使用session.userCredentialManager().method(realm, user, ...)管理用户的凭据。新方法是利用user.credentialManager().method(...)。这种形式将凭据功能更靠近用户的 API,并且不依赖于事先了解用户凭据在域和存储中的位置。

旧 API 已被弃用,并且只有在部署中启用旧存储时才能工作。新的 API 将适用于旧存储和新存储。

迁移之前:访问弃用 API
session.userCredentialManager().createCredential(realm, user, credentialModel)
迁移之后:访问新 API
user.credentialManager().createStoredCredential(credentialModel)

对于自定义UserStorageProvider,有一个需要在返回UserModel时实现的新方法credentialManager()。由于这些提供程序在启用旧存储的环境中运行,因此它们必须返回LegacyUserCredentialManager的实例。

迁移之前:代码由于UserModel要求的新方法credentialManager()而无法编译
public class MyUserStorageProvider implements UserLookupProvider, ... {
    /* ... */
    protected UserModel createAdapter(RealmModel realm, String username) {
        return new AbstractUserAdapter(session, realm, model) {
            @Override
            public String getUsername() {
                return username;
            }
        };
    }
}
迁移之后:实现UserModel.credentialManager() API 用于旧存储。
public class MyUserStorageProvider implements UserLookupProvider, ... {
    /* ... */
    protected UserModel createAdapter(RealmModel realm, String username) {
        return new AbstractUserAdapter(session, realm, model) {
            @Override
            public String getUsername() {
                return username;
            }

            @Override
            public SubjectCredentialManager credentialManager() {
                return new LegacyUserCredentialManager(session, realm, this);
            }
        };
    }
}

旧 Keycloak 运算符中已弃用的podDisruptionBudget

在此版本中,我们已弃用旧 Keycloak 运算符中 Keycloak CR 中的podDisruptionBudget字段。当运算符部署在 Kubernetes 版本 1.25 及更高版本上时,此可选字段将被忽略。

作为解决方法,您可以在集群中手动创建 Pod Disruption Budget,例如

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  labels:
    app: keycloak
  name: keycloak
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      component: keycloak

另请参阅Kubernetes 文档

新 Keycloak 运算符中的部署更改

新的 Keycloak 运算符现在使用StatefulSet而不是Deployment来部署 Keycloak。鉴于运算符在此版本中是技术预览版,因此没有自动迁移到位。如果您在 18.0.z 中使用新的运算符,请确保在升级到 19.0.0 后备份、删除并重新创建您的 Keycloak CR。

迁移到 18.0.0

升级身份验证

升级身份验证是一项新功能。此功能提供acr客户端范围,其中包含一个协议映射器,该映射器应该在令牌中添加acr声明。acr声明现在不会像此版本之前那样自动添加,但会随着此客户端范围和协议映射器的使用而添加。

客户端范围被添加为域“默认”客户端范围,因此将添加到所有新创建的客户端。出于性能原因,客户端范围不会在迁移期间自动添加到所有现有客户端。迁移后,客户端默认情况下不会具有acr声明。请考虑以下可能的行动

  • 如果您不打算使用升级身份验证功能,但依赖于令牌中的acr声明,您可以禁用step_up_authentication功能。在正常身份验证的情况下,该声明将添加值为1,在 SSO 身份验证的情况下添加值为0

  • 通过管理员 REST API 或管理员控制台手动将acr客户端范围添加到您的客户端。如果您想使用升级身份验证,则尤其需要这样做。如果您在域中拥有大量客户端,并且想对所有客户端使用acr声明,您可以对您的 DB 触发一些类似于此的 SQL。但是,请记住,如果 Keycloak 已经启动,则需要清除缓存或重新启动服务器。

insert into CLIENT_SCOPE_CLIENT (CLIENT_ID, SCOPE_ID, DEFAULT_SCOPE) select CLIENT.ID as CLIENT_ID, CLIENT_SCOPE.ID as SCOPE_ID, true as DEFAULT_SCOPE
from CLIENT_SCOPE, CLIENT where CLIENT_SCOPE.REALM_ID='test' and CLIENT_SCOPE.NAME='acr' and CLIENT.REALM_ID='test' and CLIENT.PROTOCOL='openid-connect';

OpenID Connect 注销

以前版本的 Keycloak 支持自动注销用户并通过打开注销端点 URL(例如http(s)://example-host/auth/realms/my-realm-name/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri)重定向到应用程序。虽然这种实现易于使用,但它对性能和安全性有潜在的负面影响。新版本对基于 OpenID Connect RP 发起的注销规范的注销提供了更好的支持。参数redirect_uri不再受支持;此外,在新版本中,用户需要确认注销。如果您将参数post_logout_redirect_uri与用于登录的 ID 令牌一起包含参数id_token_hint,则可以省略确认并自动重定向到应用程序。

现有的部署受到以下方式的影响

  • 如果您的应用程序直接使用带有redirect_uri参数的注销端点链接,您可能需要按照上述说明进行更改。考虑完全移除redirect_uri参数,或者将其替换为id_token_hintpost_logout_redirect_uri参数。

  • 如果您使用 java 适配器,并且您的应用程序通过调用httpServletRequest.logout()来注销,则不会受到影响,因为此调用使用注销端点的回传变体,而回传变体没有更改。

  • 如果您使用最新的 javascript 适配器,您也不会受到影响。但是,如果您的应用程序使用旧版本的 JavaScript 适配器,您会受到影响,因为此适配器使用带有弃用redirect_uri参数的注销端点变体。在这种情况下,您可能需要升级到最新版本的 JavaScript 适配器。

  • 对于 Node.js 适配器,与 JavaScript 适配器相同的准则适用。建议您更新到最新版本,因为旧版本的适配器使用已弃用的redirect_uri参数。使用最新的 Node.js 适配器,只要您使用基于/logout URL 的注销(如文档或 Node.js 适配器示例中所述),就不会受到影响。但是,如果您的应用程序直接使用keycloak.logoutUrl方法,您可以考虑将idTokenHint作为此方法的第二个参数添加。在此版本中新添加了将idTokenHint作为第二个参数添加的可能性。idTokenHint需要是在登录期间获得的有效 ID 令牌。添加idTokenHint是可选的,但如果您省略它,您的用户将需要确认注销屏幕(如前所述)。此外,他们不会在注销后被重定向回应用程序。

存在一个向后兼容选项,允许您的应用程序继续使用redirect_uri参数的旧格式。

您可以在启动服务器时启用此参数,方法是输入以下命令

bin/kc.[sh|bat] --spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true start

使用此配置,您仍然可以使用带有redirect_uri参数的格式。请注意,如果省略id_token_hint,将需要确认屏幕。

向后兼容开关将在未来的某个版本(可能是 Keycloak 23)中删除。建议您尽快按照上述说明更新您的客户端,而不是依赖此开关。

删除upload-scripts功能

以前版本的 Keycloak 支持通过管理界面(如管理控制台和 REST API)管理 JavaScript 代码。从本版本开始,这不再可能,您现在应该将脚本部署到服务器以配置以下提供程序

  • OpenID Connect 脚本映射器

  • 脚本身份验证器(身份验证执行)

  • JavaScript 策略

有关如何将脚本部署到服务器的更多详细信息,请参阅文档。请注意,要使用脚本,您仍然需要启用scripts技术预览功能。

kc.[sh|bat] start --auto-build --features=preview

部署脚本时,服务器将自动创建其相应的提供程序,以便您可以在配置身份验证流程、映射器和授权策略时选择它们。

一般而言,更新您的领域的步骤如下

  • 在升级之前,请删除您正在使用的任何脚本提供程序。

  • 升级后,请按照文档中的说明部署您的脚本。

  • 更新您的身份验证流程、映射器和客户端授权设置以使用从部署到服务器的脚本创建的提供程序。

帐户控制台 Patternfly 升级

Patternfly (PF) React 库已更新,@patternfly/react-core从 v3.153.3 更新到 v4.147.0,@patternfly/react-icons从 v3.15.16 更新到 v 4.11.8,@patternfly/react-styles从 v3.7.14 更新到 v4.11.8。对帐户控制台进行了一些细微的 UI 更新,使其与 PF 设计标准保持一致。

由于 PF 中存在重大更改,自定义开发的帐户 UI 可能与这些更新不兼容。大多数重大更改可以通过更新 PF 组件上的 props 来解决。

资源

已知存在重大更改的组件

  • 警报

  • action prop 更改为actionClose

  • 可扩展

  • 重命名为ExpandableSection

  • 标题

  • size 属性现在使用TitleSizes

  • DataListContent

  • noPadding更改为hasNoPadding

  • 网格、堆栈、级别、画廊

  • gutter属性更改为hasGutter

  • 模态

  • 大小控制从例如isLarge更改为使用ModalVariant,例如variant={ModalVariant.large}

  • 选择

  • ariaLabelTypeAheadtypeAheadAriaLabel

  • isExpandedisOpen

  • ariaLabelledByaria-labelledby

  • DataListContent

  • noPaddinghasNoPadding

Quarkus 发行版:将指标启用选项拆分为启用健康状况和启用指标

metrics-enabled选项现在仅为 Keycloak 启用指标。要启用就绪性和活动性健康端点,有一个新的布尔选项health-enabled。这允许更精细地使用这些选项,例如启用指标但不为内部部署用例启用就绪性/活动性探测。为了保持与之前设置metrics-enabled=true时相同的行为,您需要在构建 Keycloak 时额外设置health-enabled=true

迁移到 17.0.0

默认发行版现在由 Quarkus 提供支持

Keycloak 的默认发行版现在由 Quarkus 提供支持,这会对您配置 Keycloak 和部署自定义提供程序带来一些重大更改。有关更多信息,请查看Quarkus 迁移指南

Keycloak 的 WildFly 发行版现已弃用,支持将于 2022 年 6 月结束。我们建议您尽快迁移到 Quarkus 发行版。但是,如果您需要在一段时间内保留旧的 WildFly 发行版,则需要考虑一些更改

  • 旧发行版标签的容器映像已更改。要使用旧发行版,请使用标签legacy17.0.0-legacy

  • 网站上用于旧发行版的下载已更改为keycloak-legacy-17.0.0.[zip|tar.gz]

如果您在迁移到 Quarkus 发行版时遇到问题,无法配置某些功能,或者有想法和反馈,请在GitHub 讨论中发起讨论。

从预览版 Quarkus 发行版迁移

自 Keycloak 15.1.0 中发布预览版 Quarkus 发行版以来,许多方面都发生了变化。了解这些更改的最佳方法是查看新的服务器指南。总之,这些更改包括

  • 容器现在发布到quay.io/keycloak/keycloak:latestquay.io/keycloak/keycloak:17.0.0

  • 网站上的下载重命名为keycloak-17.0.0.[zip|tar.gz]

  • conf/keycloak.properties更改为conf/keycloak.conf,这统一了配置文件和 CLI 参数之间的配置键。

  • 更清晰地区分构建选项运行时配置

  • 自定义 Quarkus 配置通过conf/quarkus.properties完成。

  • h2-memh2-file数据库重命名为dev-memdev-file

  • 现在使用--features--features-disabled启用/禁用功能,取代了之前针对每个功能都有单独配置键的方法。

  • 运行时配置不再传递到kc.[sh|bat] build,也不再保留在构建中

  • 日志记录级别和格式现在使用--log-level--log-format配置,而在过去,这些必须使用不受支持的 Quarkus 属性配置。

客户端策略迁移:client-scopes

如果您使用包含 client-scopes 条件的策略并直接编辑 JSON 文档,则需要将 JSON 文档中的“scope”字段名称更改为“scopes”。

Liquibase 升级到版本 4.6.2

Liquibase 从版本 3.5.5 更新到 4.6.2,其中包括一些错误修复以及使用ServiceLoader注册自定义扩展的新方法。

从以前的 Keycloak 版本到 Keycloak 17.0.0 的迁移已在所有当前支持的数据库上进行了广泛测试,但我们要强调严格遵循升级指南的重要性,尤其是**在升级之前备份现有数据库**。尽管我们尽最大努力测试 Liquibase 升级的后果,但某些安装可能使用我们不了解的特定设置。

迁移到 16.0.0

WildFly 25 升级

WildFly 25 弃用了旧的安全子系统,该子系统除其他事项外还用于配置 TLS。由于更改数量众多,我们无法像过去那样提供迁移脚本。

我们建议您不要从 Keycloak 的以前版本复制配置文件,而是从 Keycloak 16 中提供的默认配置文件开始,并应用相关的更改。

Keycloak 子系统的配置可以直接复制。

有关 Elytron 子系统的更多信息,请参阅WildFly 文档

对于由此带来的不便,我们深表歉意,我们也理解这将使每个人都难以升级到 Keycloak 16,但我们实在找不到其他方法。

值得指出的是,我们计划在 Keycloak 17 中完全支持的 Quarkus 发行版切换将使配置和升级 Keycloak 变得更加容易。

有关 WildFly 25 的更多信息,请参阅WildFly 25 发行说明

代理环境变量

Keycloak 现在支持用于传出 HTTP 请求的标准HTTP_PROXYHTTPS_PROXYNO_PROXY环境变量。如果您定义了HTTP_PROXY变量,但没有在 SPI 配置中指定显式代理映射,则此更改可能会导致意外使用代理服务器。要阻止 Keycloak 使用这些环境变量,您可以为所有请求显式创建无代理路由,例如.*;NO_PROXY

Keycloak 运算符中的弃用功能

在此版本中,我们弃用了 Keycloak 运算符中的某些功能,或将其标记为不支持。这与 Backup CRD 和运算符管理的 Postgres 数据库有关。

Keycloak 运算符示例,包括不受支持的指标扩展

以前,在 Keycloak 运算符创建 Keycloak CR 的示例中添加了不受支持的指标扩展。此扩展已删除。

迁移到 14.0.0

客户端策略迁移

客户端策略功能自 Keycloak 12 以来一直是预览功能,没有得到适当的支持。如果您尝试过此功能并在 Keycloak 12 或 Keycloak 13 中配置了一些客户端策略或客户端配置文件,则需要在新版本中重新配置您的客户端策略和客户端配置文件。配置格式发生了重大变化,因为这只是一个预览,因此我们不提供在 Keycloak 12 或 Keycloak 13 中创建的客户端策略和客户端配置文件的自动迁移。

迁移到 13.0.0

需要手动迁移步骤

如果 standalone.xml 包含对任何 SmallRye 模块的引用,则需要手动更改。 SmallRye 模块已从底层的 WildFly 发行版中删除,如果配置引用了它们,服务器将无法启动。 因此,如果 standalone.xml 中的配置引用了这些模块,则服务器配置迁移通过 migrate-standalone.cli 失败,而不会对配置进行任何更改。 在这种情况下,要执行服务器配置迁移,您必须手动删除所有引用 SmallRye 模块的行。 在默认配置中,您需要特别删除以下行

<extension module="org.wildfly.extension.microprofile.config-smallrye"/>
<extension module="org.wildfly.extension.microprofile.health-smallrye"/>
<extension module="org.wildfly.extension.microprofile.metrics-smallrye"/>
<subsystem xmlns="urn:wildfly:microprofile-config-smallrye:1.0"/>
<subsystem xmlns="urn:wildfly:microprofile-health-smallrye:2.0" security-enabled="false" empty-liveness-checks-status="${env.MP_HEALTH_EMPTY_LIVENESS_CHECKS_STATUS:UP}" empty-readiness-checks-status="${env.MP_HEALTH_EMPTY_READINESS_CHECKS_STATUS:UP}"/>
<subsystem xmlns="urn:wildfly:microprofile-metrics-smallrye:2.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:wildfly}"/>

升级到 Wildfly 23

Keycloak 服务器已升级到使用 Wildfly 23 作为底层容器。 这不会直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 23 服务器使用的版本。 例如,Infinispan 现在是 11.0.9.Final

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。 但是,以下是您可能需要的一些最重要的更改,如果您自己进行了配置更改

  • Infinispan 缓存容器的 module 属性现在已 **弃用**(未使用)并 **替换为** modules 属性,代表与该缓存容器配置关联的模块集。 此外,由于使用 Wildfly 23 作为底层容器,各种元素的属性也发生了其他变化。 例如,managed-executor-servicemanaged-scheduled-executor-service 元素现在识别新的 hung-task-termination-period 属性。 有关详细信息,请参阅 Wildfly 23 完整模型参考

升级到 Wildfly 22

Keycloak 服务器已升级到使用 Wildfly 22 作为底层容器。 这不会直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 22 服务器使用的版本。 例如,Infinispan 现在是 11.0.8.Final

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。 但是,以下是您可能需要的一些最重要的更改,如果您自己进行了配置更改

迁移到 12.0.2

只读属性

添加了对只读用户属性的支持。 这包括用户属性,用户或管理员在使用 REST API 或 Keycloak 用户界面更新用户时不应该编辑这些属性。 尤其是在您使用以下情况时,这可能很重要

  • 自定义用户存储提供程序

  • 自定义身份验证器

  • 基于某些用户属性建立授权的自定义 JavaScript 授权策略

  • 将 X.509 证书映射到用户身份的自定义属性的 X.509 身份验证器

  • 任何其他自定义功能,其中一些用户属性用作存储身份验证/授权/身份上下文而不是简单用户配置文件信息的元数据。

有关详细信息,请参阅 威胁模型缓解章节

有效的请求 URI

如果您使用 OpenID Connect 参数 request_uri,则存在一个要求,即您的客户端需要配置 有效的请求 URI。 这可以通过管理控制台的客户端详细信息页面或通过管理 REST API 或客户端注册 API 进行配置。 有效的请求 URI 需要包含允许特定客户端使用的请求 URI 值列表。 这样做是为了避免 SSRF 攻击。 可以类似地使用通配符或相对路径,例如 有效的重定向 URI 选项,但是出于安全目的,我们通常建议使用尽可能具体的值。

迁移到 13.0.0

升级到 Wildfly 22

Keycloak 服务器已升级到使用 Wildfly 22 作为底层容器。 这不会直接涉及任何特定的 Keycloak 服务器功能,但与迁移相关的更改很少,值得一提。

依赖项更新

依赖项已更新到 Wildfly 22 服务器使用的版本。 例如,Infinispan 现在是 11.0.8.Final

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。 如果需要更多详细信息,例如,您自己进行了一些配置更改,则最重要的更改列表如下

迁移到 12.0.0

升级到 Wildfly 21

Keycloak 服务器已升级到使用 Wildfly 21 作为底层容器。 这不会直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 21 服务器使用的版本。 例如,Infinispan 现在是 11.0.4.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。 但是,以下是您可能需要的一些最重要的更改,如果您自己进行了配置更改

  • Infinispan 缓存的 object-memory 元素现在已 **弃用**(未使用)并 **替换为** heap-memory 元素。

跳过为 Docker 协议身份验证创建用户会话

使用 Docker 协议成功身份验证后,不会创建用户会话。 有关详细信息,请参阅 服务器管理指南

升级到 PatternFly 4

Keycloak 登录主题组件已升级到 PatternFly 4。 旧的 PatternFly 3 与新的同时运行,因此可以保留 PF3 组件。 但是,对登录主题的设计进行了一些更改。 请升级您的自定义登录主题以应对这些更改。 在 keycloak/examples/themes/theme/sunrise 目录中可以找到包含必要更改的示例。 不需要额外的设置。

默认情况下没有刷新令牌的客户端凭据授予

从这个 Keycloak 版本开始,OAuth2 客户端凭据授予端点默认情况下不会发出刷新令牌。 此行为符合 OAuth2 规范。 作为此更改的副作用,在成功进行客户端凭据身份验证后,Keycloak 服务器端不会创建用户会话,这将提高性能和内存使用率。 使用客户端凭据授予的客户端鼓励停止使用刷新令牌,而是始终在每次请求时使用 grant_type=client_credentials 进行身份验证,而不是使用 refresh_token 作为授予类型。 与此相关的是,Keycloak 支持在 OAuth2 吊销端点吊销访问令牌,因此允许客户端在需要时吊销单个访问令牌。

为了向后兼容,存在坚持使用旧版本的可能性。 当使用此方法时,刷新令牌仍将在使用客户端凭据授予成功进行身份验证后发出,并且还会创建用户会话。 这可以在 Keycloak 管理控制台中为特定客户端启用,在客户端详细信息中,在带有 OpenID Connect 兼容模式 的部分中,使用开关 为客户端凭据授予使用刷新令牌

迁移到 11.0.0

升级到 Wildfly 20

Keycloak 服务器已升级到使用 Wildfly 20 作为底层容器。 这不会直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 20 服务器使用的版本。 例如,Infinispan 现在是 10.1.8.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到 9.4.19 版。 较旧的版本可能仍然可以工作,但不能保证,因为它们不再经过测试。

  • 建议在配置 Infinispan 缓存时使用添加到 remote-store 元素中的 protocolVersion 属性。 连接到 Infinispan 服务器 9.4.18 时,推荐的 hotrod 协议版本是 2.9,因为 Keycloak 服务器和 Infinispan 服务器之间的 Infinispan 库版本不同。 有关详细信息,请参阅跨数据中心文档。

  • 建议使用 connectionsInfinispan 子系统下的 remoteStoreSecurityEnabled 属性。 有关详细信息,请参阅跨数据中心文档。

LDAP 不导入错误修复

在之前的 Keycloak 版本中,当 LDAP 提供程序配置为 导入用户 OFF 时,即使更改了某些非 LDAP 映射属性,也可以更新用户。 这种情况导致了令人困惑的行为,属性似乎已更新,但实际上并没有更新。 在当前版本中,如果更改了任何非 LDAP 映射属性,则根本不允许执行更新。

这不会影响大多数部署,但在某些情况下可能会受到影响。 例如,如果您之前尝试使用管理 REST API 更新用户,并且用户有一些错误的属性更改,则可以进行更新。 使用当前版本,更新是不可能的,您将立即被告知原因。

UserModel 更改

UserModel 中的 usernameemailfirstNamelastName 字段将迁移到自定义属性,作为在即将发布的版本中将更复杂的用户信息添加到 Keycloak 的准备工作。 如果数据库包含具有该确切名称的自定义属性的用户,则需要在升级之前迁移自定义属性。 此迁移不会自动进行。 否则,它们将不再从数据库中读取,并且可能会被删除。 这种情况意味着 username 现在也可以通过 UserModel.getFirstAttribute(UserModel.USERNAME) 访问和设置。 其他字段也存在类似的含义。 直接或间接子类化 UserModel 的 SPI 实现者应确保 setUsernamesetSingleAttribute(UserModel.USERNAME, …​)(以及其他字段的类似操作)之间的行为一致。 如果在评估中使用属性数量,则策略评估功能的用户必须调整其策略,因为每个用户现在默认情况下将具有四个新属性。

UserModel 的公共 API 没有变化。前端资源或访问用户数据的 SPI 无需更改。此外,数据库目前还没有变化。

Instagram IdP 迁移到新的 API

Instagram IdP 现在使用新的 API,因为旧的遗留 API 已 **弃用**。这需要获取新的 API 凭据。有关详细信息,请参阅 服务器管理指南

对于使用 Instagram IdP 的现有用户,尤其是在其为唯一身份验证选项的用户,需要特别注意。此类用户必须在 2020 年 9 月 30 日之前使用 Instagram IdP 登录 Keycloak。在那之后,他们必须使用不同的身份验证方法(如密码)登录以手动更新其 Instagram 社会链接,或在 Keycloak 中创建新帐户。这是因为 Instagram 用户 ID 在旧 API 和新 API 之间不兼容,但新 API 暂时返回新旧用户 ID 以便迁移。Keycloak 会在用户登录后自动迁移 ID。

已删除非标准令牌自省端点

在以前的版本中,Keycloak 公告了两个自省端点:token_introspection_endpointintrospection_endpoint。后者是 RFC-8414 定义的。前者先前已弃用,现已删除。

迁移到 9.0.1

JavaScript 适配器中的遗留承诺

不再需要在 JavaScript 适配器中设置 promiseType,两者同时可用。建议尽快更新应用程序以使用本机承诺 API(thencatch),因为遗留 API(successerror)将在某个时刻被移除。

重复的顶级组

版本 9.0.1 修复了一个可能会在 realm 中创建重复的顶级组的问题。但是,先前重复的组的存在会导致升级过程失败。如果 Keycloak 服务器使用的是 H2、MariaDB、MySQL 或 PostgreSQL 数据库,则可能会受到此问题的影响。在启动升级之前,请检查服务器是否包含重复的顶级组。例如,可以在数据库级别执行以下 SQL 查询以列出它们

SELECT REALM_ID, NAME, COUNT(*) FROM KEYCLOAK_GROUP WHERE PARENT_GROUP is NULL GROUP BY REALM_ID, NAME HAVING COUNT(*) > 1;

每个 realm 中只能存在一个具有相同名称的顶级组。在升级之前,应审查并删除重复项。升级中的错误包含消息 Change Set META-INF/jpa-changelog-9.0.1.xml::9.0.1- KEYCLOAK-12579-add-not-null-constraint::keycloak failed.

迁移到 9.0.0

改进的用户区域设置处理

对如何为登录页面选择区域设置以及何时更新用户的区域设置做了一些改进。

有关更多详细信息,请参见 服务器管理指南

令牌表示 Java 类中的已弃用方法

在 2038 年,int 将不再能够容纳自 1970 年以来的秒数,因此我们正在努力将其更新为 long 值。此外,令牌表示中存在另一个与处理 int 值有关的问题。默认情况下,int 会在 JSON 表示中变为 0,而它不应该包含在内。

有关已弃用方法和替换方法的详细信息,请参阅 JavaDocs。

迁移到 8.0.2

更多身份验证流程更改

REQUIRED 和 ALTERNATIVE 执行不支持在同一流程中

在以前的版本中,可以在同一个身份验证流程的同一级别上同时拥有 REQUIRED 和 ALTERNATIVE 执行。这种方法存在一些问题,我们在 Authentication SPI 中进行了重构,这意味着这不再被认为是有效的。如果 ALTERNATIVE 和 REQUIRED 执行在同一级别配置,则 ALTERNATIVE 执行将被视为禁用。因此,在迁移到最新版本时,您现有的身份验证流程将自动迁移以保持与先前版本相同的行为。如果它们在与一些 REQUIRED 执行相同的级别上包含 ALTERNATIVE 执行,那么 ALTERNATIVE 执行将被添加到单独的 REQUIRED 子流程中。这应该确保与先前版本中特定身份验证流程相同或类似的行为。我们始终建议您仔细检查身份验证流程的配置并对其进行测试,以仔细检查一切按预期工作。如果您的身份验证流程更加定制化,并且包含自定义鉴权器实现,则此建议尤其适用。

迁移到 8.0.0

新的默认主机名提供程序

旧的请求和固定主机名提供程序已被新的默认主机名提供程序替换。请求和固定主机名提供程序现在已弃用,建议尽快切换到默认主机名提供程序。

升级到 Wildfly 18

Keycloak 服务器已升级到使用 Wildfly 18 作为底层容器。这不会直接涉及任何特定的 Keycloak 服务器功能,但是请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 18 服务器使用的版本。例如,Infinispan 现在是 9.4.16.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到版本 9.4.19。较旧的版本可能仍然可以工作,但不能保证,因为我们不再对其进行测试。

将脚本部署到服务器

到目前为止,管理员可以通过 Keycloak 管理控制台以及通过 RESTful 管理 API 将脚本上传到服务器。

从现在开始,此功能默认情况下 **已禁用**,用户应优先考虑将脚本直接部署到服务器。有关更多详细信息,请参阅 JavaScript 提供程序

JavaScript 适配器中的客户端凭据

在以前的版本中,开发人员可以向 JavaScript 适配器提供客户端凭据。从现在开始,此功能已 **删除**,因为客户端应用程序无法安全地保存机密。

身份验证流程更改

我们在身份验证流程方面进行了一些重构和改进,这需要在迁移过程中注意。

已删除 OPTIONAL 执行要求

关于迁移,最重要的更改是删除了对身份验证执行中 OPTIONAL 要求的支持,并用 CONDITIONAL 要求替换它,这提供了更大的灵活性。先前版本中配置的现有 OPTIONAL 鉴权器被 CONDITIONAL 子流程替换。这些子流程配置了 Condition - User Configured 条件作为第一个执行,并将先前 OPTIONAL 鉴权器(例如 OTP Form)作为第二个执行。从用户的角度来看,身份验证过程中的行为与先前版本相同。

Java SPI 中的更改

Java Authentication SPI 和 Credential Provider SPI 中存在一些更改。Authenticator 接口没有更改,但如果您正在开发更高级的鉴权器,这些鉴权器引入了新的凭据类型(CredentialModel 的子类),您可能会受到影响。CredentialProvider 接口存在更改,并引入了一些新接口,例如 CredentialValidator。如果您 的鉴权器支持 OPTIONAL 执行要求,您也可能会受到影响。建议仔细检查服务器开发指南中的最新身份验证示例以了解更多详细信息。

Freemarker 模板更改

Freemarker 模板中存在一些更改。如果您自己的主题包含自定义的 Freemarker 模板,用于登录表单或某些帐户表单,尤其是与 OTP 相关的表单,您可能会受到影响。建议仔细检查最新 Keycloak 中的 Freemarker 模板中的更改,并根据它调整您的模板。

用户凭据更改

我们在存储用户凭据方面增加了更多灵活性。除其他事项外,每个用户可以拥有多种相同类型的凭据,例如多个 OTP 凭据。因此,对数据库模式进行了一些更改。但是,先前版本中的凭据应自动更新为新格式,用户应该仍然能够使用他们在先前版本中设置的密码或 OTP 凭据登录。

迁移到 7.0.0

升级到 Wildfly 17

Keycloak 服务器已升级到使用 Wildfly 17 作为底层容器。这不会直接涉及任何特定的 Keycloak 服务器功能,但是请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 17 服务器使用的版本。例如,Infinispan 现在是 9.4.14.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到版本 9.4.19。较旧的版本可能仍然可以工作,但不能保证,因为我们不再对其进行测试。

迁移到 6.0.0

升级到 Wildfly 16

Keycloak 服务器已升级到使用 Wildfly 16 作为底层容器。这不会直接涉及任何特定的 Keycloak 服务器功能,但是请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 16 服务器使用的版本。例如,Infinispan 现在是 9.4.8.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到版本 9.4.19。较旧的版本可能仍然可以工作,但不能保证,因为我们不再对其进行测试。

新的可选客户端范围

我们添加了一个新的 microprofile-jwt 可选客户端范围,用于处理 MicroProfile/JWT Auth 规范 中定义的声明。这个新的客户端范围定义了协议映射器,用于将已认证用户的用户名设置为 upn 声明,并将 realm 角色设置为 groups 声明。

能够将 prompt=none 传播到默认 IDP

我们在 OIDC 身份提供者配置中添加了一个名为 Accepts prompt=none forward from client 的新开关,用于识别能够处理包含 prompt=none 查询参数的转发请求的 IDP。

到目前为止,当接收到包含 prompt=none 的身份验证请求时,如果用户未在 realm 中认证,则 realm 会返回 login_required 错误,而不会检查用户是否已由 IDP 认证。从现在开始,如果可以为身份验证请求确定一个默认 IDP(通过使用 kc_idp_hint 查询参数或为 realm 设置默认 IDP),并且如果已为 IDP 启用了 Accepts prompt=none forward from client 开关,则身份验证请求将被转发到 IDP 以检查用户是否已在那里认证。

重要的是要注意,只有在指定默认 IDP 时才会考虑此开关,在这种情况下,我们知道将身份验证请求转发到哪里,而不必提示用户选择 IDP。如果无法确定默认 IDP,我们无法假设将使用哪个 IDP 来满足身份验证请求,因此不会执行请求转发。

迁移到 5.0.0

升级到 Wildfly 15

Keycloak 服务器已升级到使用 Wildfly 15 作为底层容器。这不会直接涉及任何特定的 Keycloak 服务器功能,但是请注意与迁移相关的这些更改

依赖项更新

依赖项已更新到 Wildfly 15 服务器使用的版本。例如,Infinispan 现在是 9.4.3.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到版本 9.4.19。较旧的版本可能仍然可以工作,但不能保证,因为我们不再对其进行测试。

迁移到 4.8.2

Google 身份提供者已更新为使用 Google 登录身份验证系统

Keycloak 版本 4.8.1 及之前版本的 Google 身份提供者实现依赖于 Google+ API 端点进行授权并获取用户资料。从 2019 年 3 月起,Google 将不再支持 Google+ API,转而采用新的 Google 登录身份验证系统。Keycloak 身份提供者已更新为使用新的端点,因此如果您正在使用此集成,请确保您升级到 Keycloak 4.8.2 或更高版本。

如果您遇到应用程序标识在目录中找不到的错误,则需要在 Google API 控制台 门户中重新注册客户端应用程序,以获取新的应用程序 ID 和密钥。

您可能需要调整 Google+ 用户信息端点提供的非标准声明的自定义映射器,这些声明在 Google 登录 API 中以不同的名称提供。有关可用声明的最新信息,请参阅 Google 文档。

LinkedIn 社会代理更新到 LinkedIn API 的版本 2

根据 LinkedIn 的说法,所有开发人员都需要迁移到其 API 的 2.0 版和 OAuth 2.0。因此,我们已经更新了我们的 LinkedIn 社会代理。

使用此代理的现有部署可能会在使用 LinkedIn API 的版本 2 获取用户资料时遇到错误。此错误可能与用于配置代理的客户端应用程序缺乏权限有关,该应用程序可能无权访问资料 API 或在身份验证过程中请求特定的 OAuth2 范围。

即使对于新创建的 LinkedIn 客户端应用程序,您也需要确保客户端能够至少请求 r_liteprofiler_emailaddress OAuth2 范围,以及客户端应用程序能够从 https://api.linkedin.com/v2/me 端点获取当前成员的资料。

由于 LinkedIn 对访问成员信息实施的这些隐私限制以及当前成员资料 API 返回的声明集有限,因此 LinkedIn 社会代理现在使用成员的电子邮件地址作为默认用户名。这意味着在身份验证期间发送授权请求时始终设置 r_emailaddress

迁移到 4.6.0

新的默认客户端范围

我们添加了新的 realm 默认客户端范围 rolesweb-origins。这些客户端范围包含协议映射器,用于将用户的角色和允许的 Web 来源添加到令牌中。在迁移期间,这些客户端范围应自动添加到所有 OpenID Connect 客户端作为默认客户端范围。因此,在数据库迁移完成后无需进行任何设置。

协议映射器 SPI 添加

与此相关,对(不受支持的)协议映射器 SPI 进行了一些小幅添加。只有在您实现自定义 ProtocolMapper 时才会受到影响。在 ProtocolMapper 接口上引入了一个新的 getPriority() 方法。该方法的默认实现设置为返回 0。如果您的协议映射器实现依赖于访问令牌 realmAccessresourceAccess 属性中的角色,您可能需要提高映射器的优先级。

受众解析

现在,所有在令牌中至少拥有一个客户端角色的客户端的受众都会自动添加到访问令牌中的 aud 声明中。另一方面,访问令牌可能不会自动包含为其发行的前端客户端的受众。有关更多详细信息,请阅读 服务器管理指南

JavaScript 适配器承诺

要将本机 JavaScript 承诺与 JavaScript 适配器一起使用,现在需要在 init 选项中将 promiseType 设置为 native

过去,如果本机承诺可用,则会返回一个包装器,该包装器提供传统的 Keycloak 承诺和本机承诺。这会导致问题,因为错误处理程序并不总是先于本机错误事件设置,从而导致 Uncaught (in promise) 错误。

Microsoft 身份提供者更新为使用 Microsoft Graph API

Keycloak 版本 4.5.0 及之前版本的 Microsoft 身份提供者实现依赖于 Live SDK 端点进行授权并获取用户资料。从 2018 年 11 月起,Microsoft 将不再支持 Live SDK API,转而采用新的 Microsoft Graph API。Keycloak 身份提供者已更新为使用新的端点,因此如果您正在使用此集成,请确保您升级到 Keycloak 4.6.0 或更高版本。

在“Live SDK 应用程序”下注册的传统客户端应用程序将无法与 Microsoft Graph 端点一起使用,因为应用程序的 ID 格式发生了更改。如果您遇到应用程序标识在目录中找不到的错误,则需要在 Microsoft 应用程序注册 门户中重新注册客户端应用程序,以获取新的应用程序 ID。

升级到 Wildfly 14

Keycloak 服务器已升级为使用 Wildfly 14 作为底层容器。这不会直接涉及任何特定的 Keycloak 服务器功能,但是请注意与迁移相关的这些更改

依赖项更新

依赖项已更新为 Wildfly 14 服务器使用的版本。例如,Infinispan 现在是 9.3.1.Final。

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到版本 9.4.19。较旧的版本可能仍然可以工作,但不能保证,因为我们不再对其进行测试。

迁移到 4.4.0

升级到 Wildfly 13

Keycloak 服务器已升级为使用 Wildfly 13 作为底层容器。这不会直接涉及任何特定的 Keycloak 服务器功能,但是请注意与迁移相关的这些更改

依赖项更新

依赖项已更新为 Wildfly 13 服务器使用的版本。例如,Infinispan 现在是 9.2.4.Final,Undertow 是 2.0.9.Final

配置更改

standalone(-ha).xmldomain.xml 文件中存在一些配置更改。 您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。 但是,以下是您可能需要的一些最重要的更改,如果您自己进行了配置更改

  • Infinispan 缓存中的元素 eviction 现在已弃用(未使用)并元素 object-memory 替换

  • Infinispan 子系统中的 cache-container 元素不再识别 jndi-attribute

跨数据中心复制更改
  • 您需要将 Infinispan 服务器升级到版本 9.4.19。较旧的版本可能仍然可以工作,但不能保证,因为我们不再对其进行测试。

  • 您不再需要在 Infinispan 服务器配置文件中配置安全性。

  • 需要从 Infinispan 服务器配置文件中复制缓存的配置中删除 transaction 元素。这是因为存在 infinispan 错误 https://issues.redhat.com/browse/ISPN-9323

迁移到 4.3.0

主机名配置

在以前的版本中,建议使用过滤器来指定允许的主机名。现在可以设置一个固定主机名,这使得更容易确保使用有效主机名,并且还允许内部应用程序通过备用 URL(例如内部 IP 地址)调用 Keycloak。建议您在生产环境中切换到这种方法。

迁移到 4.0.0

客户端模板更改为客户端范围

我们添加了对客户端范围的支持,这需要在迁移过程中进行一些注意。

客户端模板已更改为客户端范围

客户端模板已更改为客户端范围。如果您有任何客户端模板,它们的协议映射器和角色范围映射将被保留。

名称中的空格被替换

名称中包含空格的客户端模板已通过将空格替换为下划线进行重命名,因为客户端范围的名称中不允许使用空格。例如,客户端模板 my template 将更改为客户端范围 my_template

将客户端范围链接到客户端

对于具有客户端模板的客户端,现在将相应的客户端范围添加为 Default Client Scope 到该客户端。因此,协议映射器和角色范围映射将在客户端上保留。

realm 默认客户端范围未链接到现有客户端

在迁移期间,内置客户端范围列表将添加到每个 realm 以及 Realm Default Client Scopes 列表。但是,现有客户端不会升级,并且不会自动向它们添加新的客户端范围。此外,所有协议映射器和角色范围映射都保留在现有客户端上。在新版本中,当您创建新客户端时,它会自动附加 realm 默认客户端范围,并且不会附加任何协议映射器。我们没有在迁移期间更改现有客户端,因为不可能正确检测您可能针对客户端的协议映射器进行的自定义,例如。如果您要更新现有客户端(从它们中删除协议映射器并将它们链接到客户端范围),则需要手动执行。

需要再次确认同意

客户端范围更改需要对同意进行重构。同意现在指向客户端范围,而不是指向角色或协议映射器。由于这种变化,用户之前确认的持久同意不再有效,用户需要在迁移后再次确认同意页面。

删除了一些配置开关

从角色详细信息中删除了开关 Scope Param Required。从协议映射器详细信息中删除了开关 Consent RequiredConsent Text。这些开关已被客户端范围功能替换。

对授权服务的更改

我们添加了对 UMA 2.0 的支持。此版本的 UMA 规范对服务器如何获取权限引入了一些重要更改。

以下是 UMA 2.0 支持引入的主要更改。有关详细信息,请参阅 授权服务指南

授权 API 已删除

在 UMA 2.0(UMA 1.0)之前,客户端应用程序使用授权 API 以 RPT 格式从服务器获取权限。UMA 规范的新版本已删除授权 API,该 API 也已从 Keycloak 中删除。在 UMA 2.0 中,现在可以使用特定的授权类型从令牌端点获取 RPT。有关详细信息,请参阅 授权服务指南

授权 API 已删除

随着 UMA 2.0 的引入,我们决定利用令牌端点和 UMA 授权类型,以允许从 Keycloak 获取 RPT,并避免使用不同的 API。授权 API 提供的功能保持不变,并且在没有提供资源或范围的情况下,仍然可以从服务器获取一组一个或多个资源和范围的权限,或者获取所有权限。有关详细信息,请参阅 授权服务指南

对 UMA 发现端点的更改

UMA 发现文档已更改,有关详细信息,请参阅 授权服务指南

对 Keycloak 授权 JavaScript 适配器的更改

Keycloak 授权 JavaScript 适配器 (keycloak-authz.js) 为了符合 UMA 2.0 引入的变更而进行了修改,同时保持了与之前相同的行为。主要的变化在于如何调用 authorizationentitlement 方法,它们现在需要一个表示授权请求的特定对象类型。这种新的对象类型通过支持 UMA 授权类型支持的不同参数,在如何从服务器获取权限方面提供了更大的灵活性。

One of the main changes introduced by this release is that you are no longer required to exchange access tokens with RPTs in
order to access resources protected by a resource server (when not using UMA). Depending on how the policy enforcer is configured on the resource server side, you can just send regular
access tokens as a bearer token and permissions will still be enforced.
Keycloak 授权客户端 Java API 的变更

在升级到新版本的 Keycloak 授权客户端 Java API 时,您会注意到一些表示类已移至 org.keycloak:keycloak-core 中的不同包。

迁移到 3.4.2

在 OpenID Connect 身份验证响应中添加了 session_state 参数

OpenID Connect 会话管理规范要求 session_state 参数存在于 OpenID Connect 身份验证响应中。

在过去版本中,我们没有此参数,但现在 Keycloak 根据规范要求默认情况下添加了此参数。

但是,一些 OpenID Connect/OAuth2 适配器,尤其是旧版本的 Keycloak 适配器,可能会遇到此新参数的问题。

例如,在成功认证到客户端应用程序后,该参数将始终存在于浏览器 URL 中。在这些情况下,禁用将 session_state 参数添加到身份验证响应可能很有用。这可以通过 Keycloak 管理控制台中的特定客户端完成,在客户端详细信息中的 OpenID Connect Compatibility Modes 部分中,如 与旧适配器的兼容性 中所述。存在专用的 Exclude Session State From Authentication Response 开关,可以将其打开以防止将 session_state 参数添加到身份验证响应中。

session_state 参数是在 3.4.2 中添加的,但 Exclude Session State From Authentication Response 开关是在 4.0.0.Beta1 中添加的。如果您的 Keycloak 服务器运行的是 3.4.2 或 3.4.3,并且您在 session_state 参数方面遇到问题,则需要将服务器升级到 4.0.0.Beta1 或更高版本。

迁移到 3.2.0

新的密码哈希算法

我们添加了两种新的密码哈希算法 (pbkdf2-sha256 和 pbkdf2-sha512)。新的领域将使用 pbkdf2-sha256 哈希算法,哈希迭代次数为 27500。由于 pbkdf2-sha256 比 pbkdf2 速度稍快,因此迭代次数从 20000 增加到 27500。

如果密码策略包含哈希算法的默认值(未指定)和迭代次数(20000),则现有领域将进行升级。如果您更改了哈希迭代次数,则需要手动更改为 pbkdf2-sha256,如果您想要使用更安全的哈希算法。

ID 令牌需要 scope=openid

OpenID Connect 规范要求在初始授权请求中使用具有 openid 值的 scope 参数。因此,在 Keycloak 2.1.0 中,我们更改了适配器,以便在重定向 URI 到 Keycloak 中使用 scope=openid。现在,我们也更改了服务器部分,ID 令牌将仅在实际使用 scope=openid 时发送到应用程序。如果未使用,则 ID 令牌将被跳过,并且仅访问令牌和刷新令牌将发送到应用程序。这也允许您有意省略 ID 令牌的生成 - 例如为了节省空间或提高性能。

直接授权(OAuth2 资源所有者密码凭据授权)和服务帐户登录(OAuth2 客户端凭据授权)现在默认情况下也不使用 ID 令牌。您需要显式添加 scope=openid 参数才能包含 ID 令牌。

身份验证会话和操作令牌

我们正在努力支持多个数据中心。作为第一步,我们引入了身份验证会话和操作令牌。身份验证会话取代了先前版本中使用的客户端会话。操作令牌目前主要用于身份验证器或 requiredActionProvider 需要向用户发送电子邮件并要求用户点击电子邮件中的链接的场景。

以下是与之相关的具体更改,可能会影响您的迁移。

第一个相关的更改是在 standalone.xmlstandalone-ha.xml 中引入新的 Infinispan 缓存 authenticationSessionsactionTokens。如果您使用我们的迁移 CLI,则无需过多关注,因为您的 standalone(-ha).xml 文件将自动迁移。

第二个更改是身份验证 SPI 方法中某些签名的更改。如果您使用自定义 AuthenticatorRequiredActionProvider,这可能会影响您。AuthenticationFlowContextRequiredActionContext 类现在允许检索身份验证会话,而不是客户端会话。

我们还添加了一些对粘性会话的初步支持。如果您不希望受到影响并希望获得更好的性能,您可能希望更改您的负载均衡器/代理服务器并对其进行配置。路由已添加到新的 AUTH_SESSION_ID cookie 中。更多信息请参阅集群文档。

另一个更改是 token.getClientSession() 被删除了。这可能会影响您,例如,如果您使用的是客户端发起的身份代理链接功能。

ScriptBasedAuthenticator 将绑定名称从 clientSession 更改为 authenticationSession,因此如果您使用此身份验证器,则需要更新您的脚本。

最后,我们在管理控制台中添加了一些新的超时设置。这使您可以例如为管理员和用户自己触发的电子邮件操作指定不同的超时设置。

迁移到 2.5.1

旧脱机令牌的迁移

如果您从 2.2.0 或更早版本迁移,并且您使用了脱机令牌,那么您的脱机令牌在令牌标头中没有 KID。我们在 2.3.0 中添加了 KID 到令牌标头,并支持多个领域密钥,因此 Keycloak 可以根据令牌 KID 找到正确的密钥。

对于没有 KID 的脱机令牌,Keycloak 2.5.1 将始终使用活动领域密钥来查找用于令牌验证的正确密钥。换句话说,旧脱机令牌的迁移将起作用。因此,例如,您的用户在 1.9.8 中请求了脱机令牌,然后您从 1.9.8 迁移到 2.5.1,然后您的用户仍然能够在 2.5.1 版本中刷新他的旧脱机令牌。

但存在一个限制。一旦您更改了活动领域密钥,用户将无法再刷新旧脱机令牌。因此,在所有使用脱机令牌的用户刷新了他们的令牌之前,您不应更改活动领域密钥。显然,新刷新的令牌将在标头中包含 KID,因此在所有用户交换了他们的旧脱机令牌后,您可以自由地更改活动领域密钥。

迁移到 2.5.0

Infinispan 缓存的更改

standalone.xmlstandalone-ha.xml 配置文件中,infinispan 子系统中定义的 realms 缓存现在默认情况下具有 10000 条记录的逐出。这与 users 缓存的默认设置相同。

此外,authorization 缓存现在默认情况下没有任何逐出。

迁移到 2.4.0

服务器 SPI 拆分为服务器 SPI 和服务器 SPI 私有

keycloak-server-spi 模块已拆分为 keycloak-server-spi 和 keycloak-server-spi-private。keycloak-server-spi 中的 API 在次要版本之间不会更改,但我们保留权利,并且可能会在次要版本之间更改 keycloak-server-spi-private 中的 API。

SAML 断言中的密钥加密算法

SAML 断言和文档中的密钥现在使用 RSA-OAEP 加密方案进行加密。如果您想使用加密的断言,请确保服务提供商理解这种加密方案。在极少数情况下,如果 SP 无法处理新方案,Keycloak 可以使用旧的 RSA-v1.5 加密方案,方法是在使用系统属性 keycloak.saml.key_trans.rsa_v1.5 设置为 true 的情况下启动。

Infinispan 缓存领域和用户始终是本地的

即使您在集群中使用 Keycloak,在 standalone-ha.xml 中的 infinispan 子系统中定义的 realmsusers 缓存现在始终是本地缓存。存在一个单独的缓存 work,它处理在集群节点之间发送失效消息,并通知整个集群哪些底层 realmsusers 缓存中的记录应该失效。

迁移到 2.3.0

分页端点的默认最大结果数

所有支持分页的管理员 REST API 端点现在都有一个默认的最大结果数,设置为 100。如果您想返回超过 100 个条目,则需要使用 ?max=<RESULTS> 显式指定。

在 2.3.0 版本中,我们添加了对公钥轮换的支持。当管理员在 Keycloak 管理控制台中轮换领域密钥时,客户端适配器将能够识别它并自动从 Keycloak 下载新的公钥。但是,仅当您的适配器中没有使用 realm-public-key 选项以及硬编码的公钥时,才会执行此新的密钥自动下载。因此,我们不再建议在适配器配置中使用 realm-public-key 选项。

请注意,此选项仍然受支持,但仅当您确实想要在适配器配置中拥有硬编码的公钥并且永远不会从 Keycloak 下载公钥时,它可能很有用。从理论上讲,这样做的一个原因是在适配器和 Keycloak 之间存在不受信任的网络时,为了避免中间人攻击,但在这种情况下,使用 HTTPS 更好,它将保护适配器和 Keycloak 之间的所有请求。

添加了 Infinispan 缓存 keys

在此版本中,我们向 infinispan 子系统添加了新的缓存 keys,它在 standalone.xmlstandalone-ha.xml 配置文件中定义。它还定义了一些逐出和过期设置。此缓存用于在内部缓存服务器信任的实体(使用签名 JWT 进行身份验证的身份提供者或客户端)的外部公钥。

迁移到 2.2.0

databaseSchema 属性已弃用

JPA 和 Mongo 的 databaseSchema 属性现在已弃用,并 initializeEmptymigrationStrategy 替换initializeEmpty 可以设置为 truefalse,并控制是否应初始化一个空数据库。migrationStrategy 可以设置为 updatevalidatemanualmanual 仅支持关系数据库,并将写入一个包含数据库模式所需更改的 SQL 文件。请注意,对于 Oracle 数据库,创建的 SQL 文件包含 Oracle SQL 客户端理解的 SET DEFINE OFF 命令。如果脚本被任何其他客户端使用,请使用您选择的工具的等效命令替换这些行,以禁用变量扩展,或者如果此功能不适用,则完全将其删除。

客户端有效重定向 URI 的更改

以下场景会受到影响

  • 当在客户端中保存具有查询组件的有效重定向 URI 时(例如 http://127.0.0.1/auth?foo=bar),授权请求中的 redirect_uri 必须与该 URI(或该客户端中注册的其他 URI)完全匹配。

  • 当在客户端中保存没有查询组件的有效重定向 URI 时,redirect_uri 也必须完全匹配。

  • 当此 URI 中存在查询组件时,不再支持注册的有效重定向 URI 中的通配符,因此 redirect_uri 也需要与该保存的 URI 完全匹配。

  • 注册的有效重定向 URI 中的片段(如 http://127.0.0.1/auth#fragment)不再允许。

从身份提供者中删除默认身份验证

身份提供者不再提供将其设置为默认身份验证提供者的选项。请改为转到“身份验证”,选择浏览器流程并配置身份提供者重定向器。它提供了一个设置默认身份提供者的选项。

迁移到 2.0.0

从 1.0.0.Final 升级不再受支持

从 1.0.0.Final 升级不再受支持。要升级到此版本,请先升级到 1.9.8.Final,然后再升级到 2.0.0。

迁移到 1.9.5

默认密码哈希间隔增加到 20K

新域的默认密码哈希间隔已从 1 增加到 20K。此更改将影响用户身份验证时的性能。例如,使用旧的默认值 (1) 对密码进行哈希处理不到 1 毫秒,但使用新的默认值 (20K) 进行相同的操作可能需要 50-100 毫秒。

迁移到 1.9.3

添加用户脚本已重命名

用于将管理员用户添加到 Keycloak 的脚本已重命名为add-user-keycloak

迁移到 1.9.2

适配器选项 auth-server-url-for-backend-requests 已删除

我们已删除选项 auth-server-url-for-backend-requests,因为在某些情况下使用它会导致问题。更详细地说,可能从两个不同的上下文(内部和外部)访问 Keycloak 服务器,这会导致令牌验证等问题。

如果您仍然希望使用此选项提供的网络优化(避免应用程序通过负载均衡器发送回通道请求,而是直接发送到本地 Keycloak 服务器),您可能需要在主机配置(DNS)级别进行处理。

迁移到 1.9.0

主题和提供程序目录已移动

我们已将主题和提供程序目录从standalone/configuration/themesstandalone/configuration/providers分别移动到themesproviders。如果您已添加自定义主题和提供程序,则需要将它们移动到新位置。您还需要更新keycloak-server.json,因为它已更改。

适配器子系统仅在 Keycloak 处于打开状态时才引入依赖项

以前,如果您已将我们的 SAML 或 OIDC Keycloak 子系统适配器安装到 WildFly 或 JBoss EAP 中,我们将自动将 Keycloak 客户端 jar 包含到每个应用程序中,无论您是否正在使用 Keycloak。现在,这些库仅在为该适配器(通过子系统或 web.xml 中的 auth-method)打开 Keycloak 身份验证时添加到您的部署中。

客户端注册服务端点已移动

客户端注册服务端点已从{realm-name}/clients移动到{realm-name}/clients-registrations

身份验证响应中的会话状态参数已重命名

在 OpenID Connect 身份验证响应中,我们以前将会话状态返回为session-state,这与规范不一致,现已重命名为session_state

已弃用的 OpenID Connect 端点

在 1.2 中,我们弃用了一些与 OpenID Connect 规范不一致的端点,这些端点现已删除。这也适用于在 1.8 中被新的 introspect 端点取代的 validate 令牌端点。

对主题模板的更新

template.ftl 中的反馈已移动,格式略有更改。

模块和源代码重组

我们的大多数模块和源代码已合并到两个 Maven 模块中:keycloak-server-spi 和 keycloak-services。SPI 接口在 server-spi 中,实现位于 keycloak-services 中。所有依赖 JPA 的模块已合并到 keycloak-model-jpa 下。同样,mongo 和 Infinispan 也分别在 keycloak-model-mongo 和 keycloak-model-infinispan 模块下。

对于适配器,登录后会话 ID 已更改

为了消除安全漏洞,对于支持它的平台(Tomcat 8、Undertow/WildFly),Keycloak OIDC 和 SAML 适配器将在登录后更改会话 ID。您可以关闭此行为检查适配器配置开关。

SAML SP 客户端适配器更改

Keycloak SAML SP 客户端适配器现在需要一个特定端点/saml,以便在您的 IDP 中注册。

迁移到 1.8.0

管理员帐户

在以前的版本中,我们附带了一个具有默认密码的默认管理员用户,该用户现已删除。如果您要进行 1.8 的全新安装,则需要在第一步中创建一个管理员用户。

OAuth2 令牌自省

为了更符合 OAuth2 规范,我们添加了一个用于令牌自省的新端点。新端点可以在/realms/{realm-name}/protocols/openid-connect/token/introspect访问,它完全基于RFC-7662

/realms/{realm-name}/protocols/openid-connect/validate端点现已弃用,我们强烈建议您尽快迁移到新的自省端点。进行此更改的原因是 RFC-7662 提供了一个更标准、更安全的自省端点。

现在可以从 OpenID Connect 提供者的配置/realms/{realm-name}/.well-known/openid-configuration获取新的令牌自省 URL。您将在响应中找到一个名为token_introspection_endpoint的声明。只有机密客户端被允许调用新端点,这些客户端通常充当资源服务器,并寻找令牌元数据以执行本地授权检查。

迁移到 1.7.0.CR1

直接访问授予默认情况下对客户端禁用

为了更符合 OpenID Connect 规范,我们在管理控制台的“客户端设置”页面中添加了标志,您可以在其中启用/禁用各种 OpenID Connect/OAuth2 流程(标准流程、隐式流程、直接访问授予、服务帐户)。作为此的一部分,我们默认情况下对新客户端禁用了直接访问授予(对应于 OAuth2 的资源所有者密码凭据授予)。

从先前版本迁移的客户端仅在它们具有仅直接授予标志时才启用直接访问授予仅直接授予标志已删除,因为如果您启用直接访问授予并禁用标准+隐式流程,您将实现相同的效果。

我们还向每个域添加了内置客户端admin-cli。此客户端启用了直接访问授予。因此,如果您使用的是 Admin REST API 或 Keycloak admin-client,您应该更新您的配置以使用admin-cli代替security-admin-console,因为后者默认情况下不再启用直接访问授予。

选项“在首次登录时更新个人资料”已从身份提供者移动到“查看个人资料”身份验证器

在此版本中,我们添加了首次代理登录,它允许您指定在通过身份提供者(或社交提供者)登录新用户时应执行的操作,但尚未链接到社交帐户的 Keycloak 用户。作为此工作的一部分,我们在身份提供者中添加了选项首次登录流程,您可以在其中指定流程,然后可以在管理控制台的“身份验证”选项卡下配置此流程。

我们还从身份提供者设置中删除了选项在首次登录时更新个人资料,并将其移动到查看个人资料身份验证器的配置中。因此,一旦您指定了应为您的身份提供者使用哪个流程(默认情况下是首次代理登录流程),您就可以转到“身份验证”选项卡,选择该流程,然后在查看个人资料身份验证器下配置该选项。

web.xml 中的元素“form-error-page”不再受支持

web.xml 中的 form-error-page 将不再适用于客户端适配器身份验证错误。您必须为各种 HTTP 错误代码定义错误页面。如果您想捕获和处理适配器错误条件,请参阅文档以了解更多详细信息。

IdentityProviderMapper 更改

接口本身和方法签名没有改变。但是,行为存在一些变化。我们在本版本中添加了首次代理登录流程,并且现在在首次代理登录流程完成后调用IdentityProviderMapper.importNewUser方法。因此,如果您希望在“查看个人资料”页面中使用任何属性,您需要使用preprocessFederatedIdentity方法,而不是importNewUser。您可以通过调用BrokeredIdentityContext.setUserAttribute来设置任何属性,并且该属性将在“查看个人资料”页面上可用。

迁移到 1.6.0.Final

刷新令牌不再可重用的选项

旧版本的 Keycloak 允许多次重复使用刷新令牌。Keycloak 仍然允许这样做,但也提供了一个选项撤销刷新令牌来禁止它。该选项位于管理控制台中的令牌设置下。当刷新令牌用于获取新的访问令牌时,还会包含新的刷新令牌。启用该选项后,下次刷新访问令牌时应使用此新的刷新令牌。无法多次重复使用旧的刷新令牌。

一些包已重命名

我们进行了一些重组并重命名了一些包。这主要是关于重命名 util 类内部包。您在应用程序中使用的最重要的类(例如 AccessToken 或 KeycloakSecurityContext)以及 SPI 仍然没有变化。但是,您可能会受到轻微影响,需要更新类的导入。例如,如果您使用多租户和 KeycloakConfigResolver,您将受到影响,因为例如 HttpFacade 类已移动到不同的包中 - 现在是org.keycloak.adapters.spi.HttpFacade

持久化用户会话

我们在本版本中添加了对离线令牌的支持,这意味着我们现在将“离线”用户会话持久化到数据库中。如果您未使用离线令牌,则不会为您持久化任何内容,因此您无需关心更多数据库写入带来的性能下降。但是,在所有情况下,您都需要更新standalone/configuration/keycloak-server.json并添加userSessionPersister,如下所示:

"userSessionPersister": {
    "provider": "jpa"
},

如果您希望会话持久化到 Mongo 而不是经典的 RDBMS,请使用提供程序mongo

迁移到 1.5.0.Final

域和用户缓存提供程序

Infinispan 现在是默认的也是唯一的域和用户缓存提供程序。在非集群模式下,将使用本地 Infinispan 缓存。我们还删除了自定义内存缓存和无缓存提供程序。如果您在 keycloak-server.json 中将 realmCache 或 userCache 设置为 mem 或 none,请删除这些设置。由于 Infinispan 是唯一的提供程序,因此 realmCache 和 userCache 对象不再需要,可以删除。

使用会话提供程序

Infinispan 现在是默认的也是唯一的用户会话提供者。在非集群模式下,将使用本地 Infinispan 缓存。我们还删除了 JPA 和 Mongo 用户会话提供者。如果您在 keycloak-server.json 中将 userSession 设置为 mem、jpa 或 mongo,请将其删除。由于 Infinispan 是唯一的提供者,因此 userSession 对象不再需要,可以将其删除。

对于想要提高用户会话持久性的任何人,可以通过将用户会话缓存配置为拥有多个所有者或使用复制缓存来实现。还可以将 Infinispan 配置为持久化缓存,但这样做会影响性能。

从注册和帐户管理中删除联系信息

在默认主题中,我们现在已从注册页面和帐户管理中删除了联系信息。管理控制台现在列出了所有用户属性,而不仅仅是与联系相关的属性。管理控制台还具有向用户添加/删除属性的功能。如果您想添加联系信息,请参阅示例中包含的地址主题。

迁移到 1.3.0.Final

直接授权 API 始终启用

过去,直接授权 API(或资源所有者密码凭据)默认情况下是禁用的,并且存在在 realm 上启用它的选项。直接授权 API 现在始终启用,用于 realm 的启用/禁用选项已删除。

数据库更改

数据库中又有一些更改。请务必在升级之前备份您的数据库。

UserFederationProvider 更改

UserFederationProvider 接口中有一些细微的更改。您可能需要在升级到较新版本时同步您的实现并升级一些方法,这些方法已更改签名。更改非常小,但需要为了提高联合的性能。

WildFly 9.0.0.Final

继上一个版本中进行的发布更改之后,Keycloak 的独立下载现在基于 WildFly 9.0.0.Final。这也影响了覆盖层,覆盖层只能部署到 WildFly 9.0.0.Final 或 JBoss EAP 6.4.0.GA。服务器不再支持 WildFly 8.2.0.Final。

WildFly、JBoss EAP 和 JBoss AS7 适配器

现在有 3 个独立的适配器下载文件,分别用于 WildFly、JBoss EAP 和 JBoss AS7

  • eap6

  • wf9

  • wf8

  • as7

确保您获取了正确的适配器。

您还需要更新 standalone.xml,因为扩展模块和子系统定义已更改。有关详细信息,请参阅 保护应用程序指南

从 1.2.0.Beta1 迁移到 1.2.0.RC1

发布更改

Keycloak 现在提供 3 个下载文件:独立版、覆盖层版和演示版。独立版适用于生产环境和非 JEE 开发人员。覆盖层版旨在将 Keycloak 添加到现有的 WildFly 8.2 或 EAP 6.4 安装中,主要用于开发。最后,我们还有一个演示(或开发)版,面向想要开始使用 Keycloak 的开发人员。此版本包含 WildFly 服务器,其中包括 Keycloak 服务器和适配器。它还包含所有文档和示例。

数据库更改

此版本再次包含一些数据库更改。最重要的是应用程序和 OAuth 客户端合并。请务必在升级之前备份您的数据库。

应用程序和 OAuth 客户端合并

应用程序和 OAuth 客户端现在已合并到 Clients 中。管理控制台的 UI 和数据库也进行了更新。您的数据库数据应自动更新。以前设置的应用程序将转换为具有关闭的 同意需要 开关的客户端,而 OAuth 客户端将转换为具有打开此开关的客户端。

从 1.1.0.Final 迁移到 1.2.0.Beta1

数据库更改

此版本包含一些数据库更改。请务必在升级之前备份您的数据库。

访问令牌和 ID 令牌中的 iss

访问令牌和 ID 令牌中 iss 声明的值已从 realm name 更改为 realm url。这是 OpenID Connect 规范要求的。如果您正在使用我们的适配器,则无需进行任何更改,除非您一直在使用仅限承载者而不指定 auth-server-url,则现在必须添加它。如果您正在使用其他库(或 RSATokenVerifier),则在验证 iss 时需要进行相应的更改。

OpenID Connect 端点

为了符合 OpenID Connect 规范,身份验证和令牌端点已更改为具有单个身份验证端点和单个令牌端点。根据规范,response_typegrant_type 参数用于选择所需的流程。旧端点(/realms/{realm-name}/protocols/openid-connect/login/realms/{realm-name}/protocols/openid-connect/grants/access/realms/{realm-name}/protocols/openid-connect/refresh/realms/{realm-name}/protocols/openid-connect/access/codes)现在已弃用,将在未来版本中删除。

主题更改

主题的布局已更改。目录层次结构过去是 type/name,现在已更改为 name/type。例如,名为 sunrise 的登录主题过去部署到 standalone/configuration/themes/login/sunrise,现在已移动到 standalone/configuration/themes/sunrise/login。进行此更改是为了便于将同一主题的不同类型分组到一个文件夹中。

如果您过去将主题作为 JAR 部署,则需要创建自定义主题加载程序,这需要 Java 代码。现在已简化为仅需要一个纯文本文件 (META-INF/keycloak-themes.json) 来描述 JAR 中包含的主题。

声明更改

以前,管理控制台中存在一个专门的 Claims 选项卡,用于应用程序和 OAuth 客户端。它用于配置哪些属性应进入特定应用程序/客户端的访问令牌。它已删除,并由更灵活的协议映射器取代。

您无需关心从先前版本迁移数据库。我们对 RDBMS 和 Mongo 都进行了迁移脚本,这些脚本应确保为特定应用程序/客户端配置的声明将转换为相应的协议映射器(尽管在迁移到较新版本之前备份数据库仍然更安全)。对于从先前版本导出的 JSON 表示形式,也是如此。

社交迁移到身份代理

我们重构了社交提供者 SPI,并将其替换为更灵活的身份代理 SPI。管理控制台中的 Social 选项卡已重命名为 Identity Provider 选项卡。

同样,您无需关心从先前版本迁移数据库,就像 Claims/协议映射器一样。社交提供者配置和您用户对“社交链接”的配置都将转换为相应身份提供者。

您唯一需要执行的操作是更改特定第三方社交提供者的管理控制台中允许的 Redirect URI。您可以先进入 Keycloak 管理控制台,从配置身份提供者的页面复制 Redirect URI。然后,您可以简单地将此作为允许的 Redirect URI 粘贴到第三方提供者的管理控制台中(例如,Facebook 管理控制台)。

从 1.1.0.Beta1 迁移到 1.1.0.Beta2

  • 适配器现在是单独的下载文件。它们不包含在设备和 war 分发版中。我们现在太多了,分发版越来越臃肿。

  • org.keycloak.adapters.tomcat7.KeycloakAuthenticatorValve +org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve

  • JavaScript 适配器现在具有 idToken 和 idTokenParsed 属性。如果您使用 idToken 检索名字、电子邮件等,则需要将其更改为 idTokenParsed。

  • as7-eap-subsystem 和 keycloak-wildfly-subsystem 已合并为一个 keycloak-subsystem。如果您有现有的 standalone.xml 或 domain.xml,则需要在文件顶部附近进行编辑,并将扩展模块名称更改为 org.keycloak.keycloak-subsystem。仅对于 AS7,扩展模块名称为 org.keycloak.keycloak-as7-subsystem。

  • 不再支持在 AS7 上安装服务器。您仍然可以使用 AS7 作为应用程序客户端。

从 1.0.x.Final 迁移到 1.1.0.Beta1

  • RealmModel JPA 和 Mongo 存储模式已更改

  • UserSessionModel JPA 和 Mongo 存储模式已更改,因为这些接口已重构

  • 升级您的适配器,旧适配器与 Keycloak 1.1 不兼容。我们错误地解释了 JSON Web 令牌和 OIDC ID 令牌规范。'aud' 声明必须是客户端 ID,我们过去将 realm 名称存储在那里并对其进行验证。

从 1.0 RC-1 迁移到 RC-2

  • 许多信息级别日志记录已更改为调试级别。此外,realm 默认情况下不再具有 jboss-logging 审计侦听器。如果您想要在用户登录、注销、更改密码等操作时记录输出,请通过管理控制台启用 jboss-logging 审计侦听器。

从 1.0 Beta 4 迁移到 RC-1

  • 注销 REST API 已重构。注销 URI 上的 GET 请求不再接受 session_state 参数。您必须登录才能注销会话。您也可以将 POST 请求发送到注销 REST URI。此操作需要有效的刷新令牌才能执行注销。签名与刷新令牌相同,减去 grant type 表单参数。有关详细信息,请参阅文档。

从 1.0 Beta 1 迁移到 Beta 4

  • LDAP/AD 配置已更改。它不再位于“Settings”页面下。它现在位于 Users→Federation 下。Add Provider 将向您显示“ldap”选项。

  • 身份验证 SPI 已删除并重写。新的 SPI 是 UserFederationProvider,它更加灵活。

  • ssl-not-required +ssl-required +all +external +none

  • DB 架构再次发生变化。

  • 现在创建的应用程序默认情况下具有完整范围。这意味着,如果您不希望配置应用程序的范围,则无需进行配置。

  • 用于导入 realm 数据的 JSON 文件格式已更改。现在,角色映射位于特定用户的 JSON 记录下。

从 1.0 Alpha 4 迁移到 Beta 1

  • DB 架构已更改。我们在 Beta 1 中添加了数据库导出功能,但没有添加从旧版本导入数据库的功能。这将在以后的版本中得到支持。

  • 对于除仅限承载者应用程序以外的所有客户端,您必须至少指定一个重定向 URI。Keycloak 不会允许您登录,除非您为该应用程序指定了有效的重定向 URI。

  • 直接授权 API +ON

  • standalone/configuration/keycloak-server.json

  • JavaScript 适配器

  • 会话超时

从 1.0 Alpha 2 迁移到 Alpha 3

  • SkeletonKeyToken、SkeletonKeyScope、SkeletonKeyPrincipal 和 SkeletonKeySession 已分别重命名为:AccessToken、AccessScope、KeycloakPrincipal 和 KeycloakAuthenticatedSession。

  • ServletOAuthClient.getBearerToken() 方法签名已更改。它现在返回一个 AccessTokenResponse,以便您也可以获得刷新令牌。

  • 适配器现在会在每次请求时检查访问令牌的过期时间。如果令牌已过期,它们将尝试使用保存的刷新令牌在身份验证服务器上调用刷新操作。

  • AccessToken 中的主题已更改为用户 ID。

从 1.0 Alpha 1 迁移到 Alpha 2

  • DB 架构已更改。截至 Alpha 2,我们还没有任何数据迁移实用程序。

  • JBoss 和 WildFly 适配器现在通过 WildFly 子系统安装。请查看适配器安装文档。现在需要编辑 standalone.xml。

  • 引入了一种新的凭据类型“secret”。与其他凭据类型不同,它以纯文本形式存储在数据库中,并且可以在管理控制台中查看。

  • 不再需要应用程序和 OAuth 客户端凭据。这些客户端类型现在被硬编码为使用“secret”凭据类型。

  • 由于对应用程序和 OAuth 客户端的“secret”凭据更改,您将需要更新您的 keycloak.json 配置文件,并在管理控制台的应用程序或 OAuth 客户端凭据选项卡中重新生成一个 secret。

升级 Keycloak 服务器

您需要先升级服务器,然后再升级适配器。

准备升级

在升级服务器之前,请执行以下步骤。

步骤
  1. 关闭 Keycloak。

  2. 备份旧安装,例如配置、主题等。

  3. 如果启用了 XA 事务,请处理所有打开的事务并删除data/transaction-logs/ 事务目录。

  4. 使用关系数据库文档中的说明备份数据库。

    升级服务器后,数据库将不再与旧服务器兼容。如果您需要回滚升级,请先恢复旧安装,然后从备份副本中恢复数据库。

如果在当前设置中禁用了 persistent-user-sessions 功能并且服务器已升级,则所有用户会话将丢失,但离线用户会话除外。拥有这些会话的用户需要重新登录。请注意,在 Keycloak 服务器 26.0.0 之前的版本中,默认情况下禁用了 persistent-user-sessions 功能。

有关针对暴力破解检测失败的登录信息以及当前正在进行的身份验证流程的信息仅存储在 Keycloak 关闭时清除的内部缓存中。目前正在进行身份验证、更改密码或重置密码的用户需要在 Keycloak 重新运行后重新启动身份验证流程。

下载 Keycloak 服务器

准备升级后,您可以下载服务器。

步骤
  1. 从 Keycloak 网站下载并解压缩keycloak-26.0.5.zip

    解压缩此文件后,您应该有一个名为keycloak-26.0.5的目录。

  2. 将此目录移动到所需位置。

  3. conf/providers/themes/ 从之前的安装复制到新安装。

迁移数据库

Keycloak 可以自动迁移数据库模式,或者您可以选择手动迁移。默认情况下,当您首次启动新安装时,数据库会自动迁移。

自动关系数据库迁移

要执行自动迁移,请启动连接到所需数据库的服务器。如果数据库模式已针对新服务器版本更改,则迁移将自动启动,除非数据库中存在太多记录。

例如,在包含数百万条记录的表上创建索引可能非常耗时,并会导致重大服务中断。因此,自动迁移存在300000条记录的阈值。如果记录数超过此阈值,则不会创建索引。相反,您会在服务器日志中找到一条警告消息,其中包含您可以手动应用的 SQL 命令。

要更改阈值,请设置默认connections-liquibase 提供程序的index-creation-threshold 属性值。

kc.[sh|bat] start --spi-connections-liquibase-default-index-creation-threshold=300000

手动关系数据库迁移

要启用手动升级数据库模式,请将默认connections-jpa 提供程序的migration-strategy 属性值设置为“manual”。

kc.[sh|bat] start --spi-connections-jpa-quarkus-migration-strategy=manual

当您使用此配置启动服务器时,服务器会检查数据库是否需要迁移。所需更改将写入bin/keycloak-database-update.sql SQL 文件,您可以查看此文件并手动将其运行到数据库中。

要更改导出的 SQL 文件的路径和名称,请设置默认connections-jpa 提供程序的migration-export 属性。

kc.[sh|bat] start --spi-connections-jpa-quarkus-migration-export=<path>/<file.sql>

有关如何将此文件应用于数据库的更多详细信息,请参阅关系数据库的文档。更改写入文件后,服务器退出。

迁移主题

如果您创建了自定义主题,则必须将这些主题迁移到新服务器。此外,对内置主题的任何更改可能需要反映在您的自定义主题中,具体取决于您自定义的哪些方面。

步骤
  1. 将您的自定义主题从旧服务器的themes 目录复制到新服务器的themes 目录。

  2. 使用以下部分来迁移模板、消息和样式。

    • 如果您自定义了迁移更改中列出的任何更新的模板,请比较来自基本主题的模板,以检查您需要应用的任何更改。

    • 如果您自定义了消息,您可能需要更改键或值,或者添加其他消息。

    • 如果您自定义了任何样式并且您正在扩展 Keycloak 主题,请查看对样式的更改。如果您正在扩展基本主题,则可以跳过此步骤。

迁移模板

如果您自定义了任何模板,请查看新版本以决定是否要更新您的自定义模板。如果您进行了一些小的更改,您可以比较更新的模板和您的自定义模板。但是,如果您进行了许多更改,请考虑比较新模板和您的自定义模板。此比较将向您显示您需要进行哪些更改。

您可以使用 diff 工具来比较模板。以下屏幕截图比较了来自登录主题的info.ftl 模板和示例自定义主题

登录主题模板的更新版本与自定义登录主题模板的对比

Updated version of a Login theme template versus a custom Login theme template

此比较表明第一个更改(Hello world!!)是自定义的,而第二个更改(if pageRedirectUri)是对基本主题的更改。通过将第二个更改复制到您的自定义模板中,您已成功更新您的自定义模板。

在另一种方法中,以下屏幕截图比较了旧安装中的info.ftl 模板和新安装中更新的info.ftl 模板

旧安装中的登录主题模板与更新的登录主题模板的对比

Login theme template from the old installation versus the updated Login theme template

此比较显示了基本模板中发生了哪些更改。然后,您可以手动对修改后的模板进行相同的更改。由于这种方法更复杂,因此仅在第一种方法不可行的情况下使用此方法。

迁移消息

如果您添加了对另一种语言的支持,则需要应用上面列出的所有更改。如果您没有添加对另一种语言的支持,则可能无需更改任何内容。只有在您更改了主题中的受影响消息时,您才需要进行更改。

步骤
  1. 对于添加的值,请查看基本主题中消息的值,以确定是否需要自定义该消息。

  2. 对于重命名的键,请在自定义主题中重命名键。

  3. 对于更改的值,请查看基本主题中的值,以确定是否需要对自定义主题进行更改。

迁移样式

您可能需要更新自定义样式以反映对内置主题样式所做的更改。请考虑使用 diff 工具来比较旧服务器安装和新服务器安装之间的样式表更改。

例如

$ diff KEYCLOAK_HOME_OLD/themes/keycloak/login/resources/css/login.css \
KEYCLOAK_HOME_NEW/themes/keycloak/login/resources/css/login.css

查看更改并确定它们是否影响您的自定义样式。

升级 Keycloak 适配器

升级 Keycloak 服务器后,您可以升级适配器。早期版本的适配器可能与 Keycloak 服务器的更高版本一起使用,但 Keycloak 服务器的早期版本可能无法与适配器的更高版本一起使用。

与旧版适配器的兼容性

Keycloak 服务器的较新版本可能会与适配器的旧版本一起使用。但是,Keycloak 服务器的一些修复程序可能会破坏与适配器的旧版本的兼容性。例如,OpenID Connect 规范的新实现可能与旧的客户端适配器版本不匹配。

对于这种情况,您可以使用兼容模式。对于 OpenID Connect 客户端,管理控制台中包含客户端详细信息页面上的OpenID Connect 兼容模式。使用此选项,您可以禁用 Keycloak 服务器的一些新方面,以保持与旧客户端适配器的兼容性。有关更多详细信息,请参阅各个开关的工具提示。

升级 EAP 适配器

要升级 WildFly 适配器,请完成以下步骤

步骤
  1. 下载新的适配器存档。

  2. 通过删除WILDFLY_HOME/modules/system/add-ons/keycloak/ 目录来删除以前的适配器模块。

  3. 将下载的存档解压缩到WILDFLY_HOME 中。

升级 JavaScript 适配器

要升级 JavaScript 适配器,请安装最新版本 来自 NPM

步骤
  1. npm install keycloak-js@latest

升级 Node.js 适配器

要升级已复制到 Web 应用程序的 Node.js 适配器,请执行以下步骤。

步骤
  1. 下载新的适配器存档。

  2. 删除现有的 Node.js 适配器目录

  3. 将更新的文件解压缩到其位置

  4. 更改应用程序 package.json 中的 keycloak-connect 依赖项

升级 Keycloak 客户端库

客户端库是这些工件

  • Java 管理客户端 - Maven 工件 org.keycloak:keycloak-admin-client

  • Java 授权客户端 - Maven 工件 org.keycloak:keycloak-authz-client

  • Java 策略执行器 - Maven 工件 org.keycloak:keycloak-policy-enforcer

客户端库支持最后一个支持的 Keycloak 服务器版本。

客户端库可能与旧版本的 Keycloak 服务器一起使用,但不能保证并得到官方支持。

可能需要查看客户端库(如 Java 管理客户端)的 javadoc,以查看哪些端点和参数支持哪个 Keycloak 服务器版本。