升级 Keycloak
本指南介绍如何升级 Keycloak。请按以下顺序使用以下步骤
-
查看先前 Keycloak 版本的迁移变更。
-
升级 Keycloak 服务器。
-
升级 Keycloak adapters。
-
升级 Keycloak 客户端库(Admin client、Authorization client、Policy enforcer)。这些库独立于 Keycloak 服务器发布,并且通常可以独立于 Keycloak 服务器进行更新,因为最新发布的客户端库版本应与最新发布的 Keycloak 服务器版本兼容。有关更多信息,请参阅 升级 Keycloak 客户端库。
迁移变更
迁移到 26.2.0
重大变更
重大变更被定义为需要现有用户对其配置进行更改。
X-Forwarded-Host
标头端口行为的更改
X-Forwarded-Host
标头可以选择也包含端口。在以前的版本中,当标头中省略端口时,Keycloak 会回退到实际的请求端口。例如,如果 Keycloak 监听端口 8080,并且请求包含 X-Forwarded-Host: example.com
标头,则解析的 URL 为 http://example.com:8080
。
现在已更改,省略端口会导致从解析的 URL 中删除端口。先前示例中解析的 URL 现在将为 http://example.com
。
为了缓解这种情况,请让您的反向代理在 X-Forwarded-Host
标头中包含端口,或者将其配置为设置包含所需端口的 X-Forwarded-Port
标头。
安装 Oracle JDBC 驱动程序的更改
需要显式添加到发行版的 Oracle JDBC 驱动程序所需的 JAR 已更改。请使用 ojdbc17
JAR 而不是提供 ojdbc11
JAR,如安装 Oracle 数据库驱动程序指南中所述。
JWT 客户端身份验证与最新的 OIDC 规范对齐
OpenID Connect 核心规范的最新草案版本更改了客户端身份验证方法 private_key_jwt
和 client_secret_jwt
的 JWT 客户端断言中受众验证的规则。
以前,JWT 客户端断言的 aud
claim 被松散地定义为“受众应该是授权服务器令牌端点的 URL”,这并不排除使用其他 URL。
修订后的 OIDC Core 规范使用了更严格的受众检查:“受众值必须是以字符串形式传递的 OP 的 Issuer Identifier,而不是单元素数组。”。
我们调整了 private_key_jwt
和 client_secret_jwt
的 JWT 客户端身份验证器,默认情况下仅允许令牌中包含单个受众。目前,受众可以是 issuer、令牌端点、自省端点或客户端 JWT 身份验证使用的其他 OAuth/OIDC 端点。但是,由于现在仅允许单个受众,这意味着不可能使用其他不相关的受众值,这是为了确保 JWT 令牌确实仅对 Keycloak 的客户端身份验证有用。
通过 OIDC 登录协议 SPI 的新选项,可以将此严格的受众检查恢复为以前更宽松的检查。如果服务器使用以下选项启动,则仍然允许在 JWT 中使用多个受众
--spi-login-protocol-openid-connect-allow-multiple-audiences-for-jwt-client-authentication=true
请注意,此选项将来可能会被删除。可能在 Keycloak 27 中。因此,强烈建议您更新客户端以使用单个受众,而不是使用此选项。还建议您的客户端在发送 JWT 进行客户端身份验证时使用 issuer URL 作为受众,因为这将与未来版本的 OIDC 规范兼容。
值得注意的变更
值得注意的变更是指内部行为的更改,旨在防止常见的错误配置、修复错误或简化 Keycloak 的运行。
内置 X509 客户端证书查找提供程序强制执行 proxy-trusted-addresses
内置 X.509 客户端证书查找提供程序现在反映了 proxy-trusted-addresses
配置选项。只有在代理受信任或 proxy-trusted-addresses
未设置的情况下,才会处理通过 HTTP 标头提供的证书。
零配置安全集群通信
对于集群多个节点,Keycloak 使用分布式缓存。从此版本开始,对于所有基于 TCP 的传输堆栈,节点之间的通信都使用 TLS 加密,并使用自动生成的临时密钥和证书进行保护。
如果您未使用基于 TCP 的传输堆栈,建议迁移到 jdbc-ping
传输堆栈,以从简化的配置和增强的安全性中受益。
如果您在以前的版本中提供了自己的密钥库和信任存储来保护 TCP 传输堆栈通信,那么现在建议迁移到自动生成的临时密钥和证书,以从简化的设置中受益。
如果您正在使用自定义传输堆栈,则可以通过将选项 cache-embedded-mtls-enabled
设置为 false
来禁用此默认行为。
有关更多信息,请查看分布式缓存指南中的保护传输堆栈。
Operator 创建 NetworkPolicy 以限制流量
Keycloak Operator 现在默认创建 NetworkPolicy,以限制流向 Keycloak 分布式缓存使用的内部端口的流量。
这加强了默认安全设置,并最大程度地减少了新设置的配置步骤。我们希望这向后兼容现有部署,因此在升级时无需执行其他步骤。您可以通过在 Keycloak CR 中禁用 NetworkPolicy 的创建来返回到先前的行为。
如果您的部署脚本为 Keycloak 添加了显式的 NetworkPolicy,您应该考虑删除这些策略,并在升级后迁移到 Keycloak CR 中提供的新功能。
在 Operator 高级配置中阅读有关此内容的更多信息。
支持的标准令牌交换
在此版本中,Keycloak 添加了对标准令牌交换(功能 token-exchange-standard:v2
)的支持。在过去的 Keycloak 版本中,Keycloak 仅具有预览令牌交换功能,该功能现在称为旧版令牌交换(功能 token-exchange:v1
)。旧版令牌交换仍处于预览状态,其工作方式与以前的版本相同。如果您使用了内部到内部令牌交换,请考虑迁移到新的标准令牌交换。
如果您希望继续使用旧版令牌交换,您会发现它的操作与以前的版本相同。无需禁用标准令牌交换功能。您的客户端仅在 Keycloak 客户端上启用标准令牌交换时才会使用它。但是,建议迁移到标准令牌交换。它是官方支持的方法,也是增强功能的优先事项。
在计划迁移到新的标准令牌交换时,请考虑以下注意事项
-
功能
token-exchange-standard
(表示新的标准令牌交换)默认启用。建议禁用token-exchange
功能(表示旧版令牌交换),以确保请求将由新的标准令牌交换提供服务。 -
您可以同时启用标准和旧版令牌交换功能,如果您需要涵盖标准用例(内部到内部)以及仅由旧版令牌交换实现的其他令牌交换用例,这将非常有用。例如,外部到内部令牌交换仅由旧版令牌交换实现。在这种情况下,Keycloak 最好通过标准令牌交换来服务标准的内部到内部请求,而其他请求由旧版令牌交换提供服务。标准或旧版令牌交换的选择取决于特定请求的参数。例如,包含非标准参数(如
requested_issuer
或requested_subject
)的请求被视为旧版。如果您仍然需要旧版令牌交换,则还需要启用细粒度管理权限版本 1 (FGAP:v1),因为版本 2 (FGAP:v2) 不支持令牌交换权限。这是有意的,因为令牌交换在概念上并不是真正的“管理”权限,因此令牌交换权限未添加到 FGAP:v2。
-
标准令牌交换需要在客户端上启用开关,如令牌交换文档中所述。
请考虑以下两种类型的令牌交换行为的其他更改
-
标准令牌交换不再需要或支持细粒度管理权限。
-
关于 scope 和受众行为的最值得注意的更改是,应用的客户端 scope 基于触发令牌交换请求的客户端,而不是由
audience
参数指定的“目标”客户端。支持audience
参数的多个值,如规范中所述。令牌交换文档中描述了详细信息。 -
不再允许公共客户端发送令牌交换请求。旧版令牌交换允许公共客户端与自身交换令牌以缩小原始令牌的 scope。相反,此用例可以通过使用刷新令牌授权来覆盖,其中可以使用
scope
参数来缩小刷新的访问令牌的 scope,如OAuth2 规范中所述。 -
此版本不支持将访问令牌交换为 SAML 断言。换句话说,不支持使用
requested_token_type=urn:ietf:params:oauth:token-type:saml2
。 -
只有当客户端显式启用令牌交换功能时,才允许交换访问令牌以获取刷新令牌,如令牌交换文档中所述。目前,不支持请求离线令牌或在主题令牌从离线会话颁发时交换刷新令牌。建议尽可能交换访问令牌而不是刷新令牌。
支持细粒度管理员权限
从本版本开始,Keycloak 引入了 细粒度管理员权限 V2 ,为管理权限提供了改进且更灵活的授权模型。
-
FGAP:V2 功能默认启用。
-
FGAP:V1 功能仍处于预览状态,可以使用
--features=admin-fine-grained-authz:v1
启用。但是,V1 可能会在未来的版本中被弃用和移除。
从 V1 迁移到 V2
由于权限模型的根本性变化, 无法进行从 V1 到 V2 的自动迁移 。为了简化过渡
-
引入了一个新的
admin-permissions
客户端。当您为 realm 启用此功能时,将创建此客户端。该客户端持有 FGAP:V2 的授权模型。 -
现有的 FGAP:V1 授权模型在
realm-management
客户端中保持不变。 -
管理员必须使用新模型 重新创建权限和策略 ,这可以在更新后的管理控制台的 权限 部分中配置。
FGAP:V1 和 FGAP:V2 之间的主要区别
-
Realm 级别启用
-
可以使用 Realm 设置 中的新 管理员权限 开关为 realm 启用 FGAP:V2。
-
-
集中式管理
-
资源特定的 权限 选项卡(用于用户、组、客户端和角色)已被移除。
-
新的 权限 部分为管理控制台中所有管理权限提供集中式管理。
-
-
显式操作范围界定
-
权限之间的传递依赖关系已被移除。
-
管理员现在必须显式分配每个所需的权限。
-
示例:要查看和管理资源,必须分别分配权限的 view 和 manage 范围。
-
-
权限模型更改
-
user-impersonated 用户权限已被 移除 。
-
configure 客户端权限已被 移除 。随着 V2 中显式操作范围界定的引入,manage 和 configure 之间的区别变得模糊不清。
-
user-impersonated 用户权限已被 移除 。相反,您可以使用
Groups
资源类型的impersonate-members
范围来允许或拒绝模拟组成员。 -
manage-members
组权限不允许 realm 管理员从组中取消分配成员。原因是,在 V1 中,这允许组成员成为常规 realm 用户,以及创建 realm 中用户的变通权限。未来,我们将努力提供额外的范围来允许从组中删除成员。
-
-
灵活的资源范围界定
-
与 V1 不同,V1 中的权限要么授予 单个资源 (对于客户端、组和角色),要么授予 所有资源 (对于用户),V2 引入了更大的灵活性。
-
管理员现在可以为以下对象定义权限
-
特定资源
-
一组选定的资源
-
给定类型的所有 所有资源
-
这适用于 所有资源类型 :客户端、用户、组和角色。
-
-
LDAP 提供程序现在可以将新用户、组和角色存储在基本 DN 的子 DN 中
添加新用户、组或角色时,LDAP 提供程序始终将它们存储在为搜索配置的同一基本 DN 中。但是,在某些部署中,管理员可能希望配置具有 subtree
范围的更广泛的 DN,以从多个子 DN 获取用户(或组/角色),但他们不希望新用户(或组/角色)存储在 LDAP 中的此基本 DN 中。相反,他们希望选择其中一个子 DN 来执行此操作。
现在可以使用 LDAP 提供程序以及 LDAP 组和角色映射器中的新 Relative User Creation DN
配置选项来控制将在何处创建新用户、组或角色。有关更多详细信息,请查看 LDAP 管理指南
移除 X-XSS-Protection
标头
由于 X-XSS-Protection
标头 不再受 Keycloak 支持的任何用户代理支持,因此已将其移除。此标头是 Internet Explorer、Chrome 和 Safari 的一项功能,当它们检测到反射型跨站脚本 (XSS) 攻击时,会阻止页面加载。
我们预计这不会影响任何部署,因为用户代理缺乏支持,并且此功能已被 内容安全策略 (CSP) 取代。
JWT 客户端身份验证为令牌定义了新的最大过期时间选项
当客户端配置为使用 Signed JWT 或 Signed JWT with Client Secret 类型进行身份验证时,Keycloak 现在强制执行令牌的最大过期时间。这意味着,尽管令牌中的 exp
(过期)声明可能晚得多,但 Keycloak 将不接受在此最大过期时间之前颁发的令牌。默认值为 60 秒。请注意,JWT 令牌应在发送以进行身份验证之前立即颁发。这样,客户端就有一分钟的窗口时间来发送令牌以进行登录。尽管如此,可以使用客户端 凭据 选项卡中的 最大过期时间 配置选项来调整此过期时间(有关更多信息,请参阅 服务器管理指南中的机密客户端凭据)。
迁移到 26.1.3
值得注意的更改
值得注意的变更是指内部行为的更改,旨在防止常见的错误配置、修复错误或简化 Keycloak 的运行。
发送重置电子邮件,强制联合用户在重置凭据后再次登录
以前,如果使用相同的身份验证会话(相同的浏览器),则重置凭据流程( 忘记密码 功能)会在重置凭据后保持用户登录状态。对于联合用户提供程序,此行为可能存在安全问题。想象一下,一个提供程序实现检测到用户为 已启用 ,成功执行了密码更改,但由于某种原因,用户密码的验证失败。在这种情况下,重置凭据流程允许用户在成功的密码更改后登录,而使用正常的浏览器流程本应不允许登录。这种情况并不常见,但默认情况下应避免。
因此,现在身份验证器 reset-credential-email
( 发送重置电子邮件 )有一个名为 force-login
( 重置后强制登录 )的新配置选项,其值为 true
(始终强制登录)、 false
(之前的行为,如果使用相同的身份验证会话,则保持用户登录状态)和 only-federated
(默认值,强制联合用户再次进行身份验证,并保持存储在 Keycloak 内部数据库中的用户的先前行为)。
有关更改此选项的更多信息,请参阅 启用忘记密码。
迁移到 26.1.0
值得注意的更改
值得注意的变更是指内部行为的更改,旨在防止常见的错误配置、修复错误或简化 Keycloak 的运行。
如果在初始交换中请求 offline_scope
,则离线访问会移除关联的在线会话
Keycloak 中的任何离线会话都是从在线会话创建的。当请求 offline_access
范围时,当前在线会话用于为客户端创建关联的离线会话。因此,到目前为止,任何 offline_access
请求完成都会创建两个会话:一个在线会话和一个离线会话。这种情况导致了不可靠的行为。例如,当仅请求使用 scope=offline_access
登录时,可能会创建一个未使用的在线会话,这在大多数情况下是无用的。这种情况导致了服务器资源的非必要消耗。
从本版本开始,如果 offline_scope
直接作为会话的首次交互请求,Keycloak 将移除初始在线会话。客户端在与离线会话关联的代码到令牌交换后检索离线令牌,但之前的在线会话将被移除。如果在线会话在 offline_scope
请求之前已被同一客户端或另一个客户端使用,则在线会话将像今天一样保持活动状态。这种情况也意味着,如果使用 scope=offline_access
的登录请求,并且用户之前尚未在 SSO 中进行身份验证,则不会在浏览器中创建 SSO 会话。尽管新行为是有道理的,因为客户端应用程序只是请求离线令牌,但这可能会影响某些依赖于在初始 offline_scope
令牌请求后在线会话仍然处于活动状态的场景。
新的客户端范围 service_account
用于 client_credentials
授权映射器
Keycloak 在 realm 级别引入了一个新的客户端范围,称为 service_account
,它负责通过协议映射器为 client_credentials
授权( client_id
、 clientHost
和 clientAddress
)添加特定声明。当客户端配置中设置或取消设置 serviceAccountsEnabled
选项时,此范围将自动分配给客户端并从客户端取消分配。
以前,当客户端配置为启用服务帐户时,这三个映射器( Client Id
、 Client Host
和 Client IP Address
)直接添加到专用范围,并且永远不会被移除。
对于大多数 Keycloak 部署来说,行为应该基本相同,因为令牌中的声明与以前基本相同。在您使用客户端凭据授权并且您正在通过一些手动移除或更新上述三个协议映射器的工具来准备 Keycloak 环境的情况下,您可能会受到影响。例如,如果您使用管理员 CLI 脚本为客户端启用服务帐户,然后移除内置的服务帐户协议映射器,您可以调整您的 CLI 以改为移除客户端的 service_account
客户端范围的分配,而不是移除协议映射器。
弃用通知
此处列出了在本版本中继续像以前一样工作的功能,但在未来的主要版本中将被移除。
生产环境的默认 db
选项已弃用。
在以前的版本中, db
选项在生产 ( start
) 模式和开发 ( start-dev
) 模式下都默认为 dev-file
,而 dev-file
从未在生产模式下受支持。在本版本中,我们已弃用此行为,在未来的某个版本中, db
选项在生产模式下将不再默认为 dev-file
。对于生产配置文件中的 build
或非优化 start
和非服务器命令 import
、 export
或 bootstrap-admin
,应显式提供值。这是为了防止在生产环境中意外使用 dev-file
(H2) 数据库,这通常表明配置错误。
JavaScript Authorization 客户端的已弃用 API
JavaScript Authorization 客户端的以下 API 已弃用,将在下一个主要版本中移除
-
KeycloakAuthorization
实例上的ready
属性。 -
KeycloakAuthorization
实例上的init()
方法。
这些 API 不再需要,因为初始化在调用 KeycloakAuthorization
实例上的方法时按需自动完成。您可以安全地移除任何依赖于这些 API 的代码。
用于从 OIDC 客户端启动注册的已弃用端点
用于通过 OIDC 客户端启动注册的 /realms/<realm>/protocol/openid-connect/registrations
端点现已弃用,因为存在从 OIDC 客户端启动注册的标准方法。Keycloak 现在支持这种方法。它使用参数 prompt=create
。
迁移到 26.0.0
Infinispan 编组更改
编组是将 Java 对象转换为字节的过程,以便在 Keycloak 服务器之间通过网络发送它们。在 Keycloak 26 中,编组库已从 JBoss Marshalling 更改为 Infinispan Protostream。这些库彼此不兼容,并且需要一些步骤来确保会话数据不会丢失。
JBoss Marshalling 和 Infinispan Protostream 彼此不兼容,不正确的使用可能会导致数据丢失。因此,升级到此版本时,所有缓存都会被清除。 |
为了防止丢失用户会话,请先升级到 Keycloak 25,并按照 Keycloak 25 的迁移指南中概述的方式启用持久会话功能。
Operator 不再默认为 proxy=passthrough
Operator 将不再默认为 hostname v1 设置 proxy=passthrough。这允许使用 hostname v2 进行固定边缘主机名的部署按预期工作,而无需其他选项。
ClusterProvider
API 中的新方法
以下方法已添加到 org.keycloak.cluster.ClusterProvider
-
void notify(String taskKey, Collection<? extends ClusterEvent> events, boolean ignoreSender, DCNotify dcNotify)
当多个事件发送到同一 taskKey
时,此方法会批量处理事件,并且仅执行单个网络调用。这是一种优化,旨在减少流量和网络相关资源。
在 Keycloak 26 中,新方法具有默认实现,以保持与自定义实现的向后兼容性。默认实现为每个事件执行单个网络调用,并且将在 Keycloak 的未来版本中移除。
移除 realm 时不再触发与组相关的事件
为了提高组的可伸缩性,现在在移除 realm 时直接从数据库中移除组。因此,在移除 realm 时不再触发组相关事件,如 GroupRemovedEvent
。
如果您有扩展程序在移除 realm 时处理任何组相关事件,请确保改为使用 RealmRemovedEvent
,以便在移除 realm 及其组时执行任何清理或自定义处理。
GroupProvider
接口也已更新,添加了一个新的 preRemove(RealmModel)
方法,以强制实现正确处理在移除 realm 时移除组的情况。
从根路径自动重定向到相对路径
当指定 http-relative-path
属性时,用户会自动重定向到 Keycloak 托管的路径。这意味着当相对路径设置为 /auth
,并且用户访问 localhost:8080/
时,页面将重定向到 localhost:8080/auth
。
当指定 http-management-relative-path
或 http-relative-path
属性时,管理界面也适用相同的情况。
这改善了用户体验,因为用户不再需要显式地将相对路径设置为 URL。
Operator 调度默认值
Keycloak Pod 现在将具有默认的亲和性,以防止来自同一 CR 的多个实例部署在同一节点上,并且来自同一 CR 的所有 Pod 将优先位于同一区域中,以防止拉伸缓存集群。
Operator 的默认 CPU 和内存限制/请求
为了遵循最佳实践,引入了 Operator 的默认 CPU 和内存限制/请求。这会影响非 OLM 安装和 OLM 安装。要覆盖 OLM 安装的默认值,请编辑 operator 的 subscription 中的 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
URL 编码一致使用 UTF-8 字符集
org.keycloak.common.util.Encode
现在始终使用 UTF-8
字符集进行 URL 编码,而不是隐式依赖于 file.encoding
系统属性。
配置 LDAP 连接池
在本版本中,LDAP 连接池配置完全依赖于系统属性。主要原因是 LDAP 连接池配置是 JVM 级别的配置,而不是特定于单个 realm 或 LDAP 提供程序实例的配置。
与以前的版本相比,任何与 LDAP 连接池相关的 realm 配置都将被忽略。如果您是从以前的版本迁移而来,并且以下任何设置已设置为您的 LDAP 提供程序,请考虑改用系统属性
-
connectionPoolingAuthentication
-
connectionPoolingInitSize
-
connectionPoolingMaxSize
-
connectionPoolingPrefSize
-
connectionPoolingTimeout
-
connectionPoolingProtocol
-
connectionPoolingDebug
有关更多详细信息,请参阅 配置连接池。
登录主题中的自定义页脚
此版本引入了轻松地为 base/login
和 keycloak.v2/login
主题的登录页面添加自定义页脚的功能。为了使用自定义页脚,请在您的自定义登录主题中创建一个包含所需内容的 footer.ftl
文件。
有关更多详细信息,请参阅 向登录主题添加自定义页脚。
跨重启持久化吊销的访问令牌
在本版本中,当使用嵌入式缓存时,吊销的访问令牌默认写入数据库并在集群重启时重新加载。
要禁用此行为,请使用 SPI 选项 spi-single-use-object-infinispan-persist-revoked-tokens
,如 所有提供程序配置 指南中所述。
SingleUseObjectProvider
的 SPI 行为已更改,对于吊销的令牌,仅必须使用方法 put
和 contains
。默认情况下强制执行此操作,并且可以使用 SPI 选项 spi-single-use-object-infinispan-persist-revoked-tokens
禁用。
高可用性多站点部署
Keycloak 26 对推荐的 HA 多站点架构进行了重大改进,最值得注意的是
-
Keycloak 部署现在能够同时在两个站点中处理用户请求。以前一次仅在一个站点中处理请求的负载均衡器配置将继续工作。
-
现在需要主动监控站点之间的连接,以便在发生故障时在站点之间进行复制。蓝图描述了使用 Alertmanager 和 AWS Lambda 的设置。
-
负载均衡器蓝图已更新为使用 AWS Global Accelerator,因为这避免了客户端 DNS 缓存导致的长时间故障转移时间。
-
持久用户会话现在是架构的要求。因此,用户会话将在 Keycloak 或 Infinispan 升级时保留。
-
外部 Infinispan 请求处理已得到改进,以减少内存使用量和请求延迟。
由于上述更改,您的现有 Keycloak 部署需要进行以下更改。
-
当启用
multi-site
功能时,缓存配置文件提供的distributed-cache
定义将被忽略,因此您必须通过cache-remote-*
命令行参数或 Keycloak CR 配置与外部 Infinispan 部署的连接,如蓝图中概述的那样。所有remote-store
配置都必须从缓存配置文件中移除。 -
查看您当前在外部 Infinispan 中的缓存配置,并使用 Keycloak 文档最新版本中概述的配置更新它们。虽然以前版本的缓存配置仅在站点之间的备份复制失败时记录警告,但新配置确保两个站点的状态保持同步:当两个站点之间的传输失败时,调用者将看到错误。因此,您需要设置监控以在站点故障时断开两个站点的连接。《Keycloak 高可用性指南》包含有关如何设置此功能的蓝图。
-
虽然以前的负载均衡器配置将继续与 Keycloak 一起工作,但请考虑升级现有的 Route53 配置,以避免客户端 DNS 缓存导致的长时间故障转移时间。
-
如果您已使用 remote-store 配置更新了缓存配置文件 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_ADMIN
和 KEYCLOAK_ADMIN_PASSWORD
已弃用。您应该改用 KC_BOOTSTRAP_ADMIN_USERNAME
和 KC_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-name}/identity-provider/instances
端点。此端点支持过滤器和分页。
CLI 导入占位符替换
CLI 命令 kc.[sh|bat] import
现在已启用占位符替换。以前,占位符替换仅在启动时为 realm 导入启用。
如果您希望禁用 import
命令的占位符替换,请添加系统属性 -Dkeycloak.migration.replace-placeholders=false
新的 Java API,用于按名称搜索 realm
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-type
和 https-trust-store-type
来覆盖自动检测。管理界面及其 https-management-key-store-type
也适用相同的情况。FIPS 严格模式的限制保持不变。
spi-truststore-file-* 选项和信任库相关选项 https-trust-store-* 已弃用,我们强烈建议使用系统信任库。有关更多详细信息,请参阅相关的 指南。 |
提高选择身份提供程序的性能
在 IDENTITY_PROVIDER
表中添加了新索引,以提高查询性能,这些查询用于获取与组织关联的 IDP,以及获取可用于登录的 IDP(已 enabled
、非 link_only
、未标记为 hide_on_login
的 IDP)。
如果该表当前包含超过 300,000 个条目,则默认情况下,Keycloak 将在自动模式迁移期间跳过索引的创建,而是在迁移期间在控制台上记录 SQL 语句。在这种情况下,必须在 Keycloak 启动后在数据库中手动运行这些语句。
此外, kc.org
和 hideOnLoginPage
配置属性已迁移到身份提供程序本身,以便在搜索提供程序时进行更高效的查询。因此,API 客户端应使用 IdentityProviderRepresentation
中的 getOrganizationId/setOrganizationId
和 isHideOnLogin/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) 和初始迁移指南。
默认情况下,所有用户会话都会持久化
由于数据库现在是用户会话的真实来源,因此可以限制会话缓存的大小以减少内存使用量。如果您使用默认的 conf/cache-ispn.xml
文件,则用于存储用户和客户端会话的缓存默认配置为仅存储 10000 个会话,并且每个条目有一个所有者。
使用类似于下面所示的配置更新您的自定义嵌入式 Infinispan 缓存配置文件,用于缓存 sessions
、clientSessions
、offlineSessions
和 offlineClientSessions
<distributed-cache name="sessions" owners="1"> <!-- other configuration --> <memory max-count="10000"/> </distributed-cache>
有关更多详细信息,请访问配置分布式缓存指南。
启用持久会话后,空闲会话的宽限期已移除
以前版本的 Keycloak 为用户和客户端会话的空闲时间添加了两分钟的宽限期。这是由于以前的架构中会话刷新时间在集群中异步复制而添加的。使用持久用户会话后,这不再是必需的,因此现在移除了宽限期。
要保留旧的行为,请更新您的 realm 配置,并将会话和客户端空闲时间延长两分钟。
已移除对旧版 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
或通过任何其他不带 --optimized
标志的服务器命令(如 start
、export
、import
)来实现。
适配器和 misc BOM 文件已移除
org.keycloak.bom:keycloak-adapter-bom
和 org.keycloak.bom:keycloak-misc-bom
BOM 文件已移除。适配器 BOM 不再有用,因为大多数 Java 适配器已被移除。misc BOM 仅包含一个构件,keycloak-test-helper
,并且该构件也已在此版本中移除。
keycloak-test-helper 已移除
maven 构件 org.keycloak:keycloak-test-helper
已在此版本中移除。该构件为处理 Java 管理客户端提供了一些辅助方法。如果您使用这些辅助方法,则可以在需要时将它们 fork 到您的应用程序中。
凭据的新的通用事件类型
现在有用于更新 (UPDATE_CREDENTIAL
) 和移除 (REMOVE_CREDENTIAL
) 凭据的通用事件。凭据类型在事件的 credential_type
属性中描述。电子邮件事件侦听器支持新的事件类型。
以下事件类型现在已弃用,将在未来版本中移除:UPDATE_PASSWORD
、UPDATE_PASSWORD_ERROR
、UPDATE_TOTP
、UPDATE_TOTP_ERROR
、REMOVE_TOTP
、REMOVE_TOTP_ERROR
--import-realm
选项可以导入 master realm
当在 master realm 存在之前使用 --import-realm
选项运行 start
或 start-dev
命令时,如果 master realm 存在于导入材料中,则会导入它。之前的行为是首先创建 master realm,然后跳过其导入。
BouncyCastle FIPS 已更新
我们的 FIPS 140-2 集成现在已通过 BouncyCastle FIPS 库版本 2 的测试和支持。此版本已通过 Java 21 认证。如果您使用 FIPS 140-2 集成,建议将 BouncyCastle FIPS 库升级到最新文档中提到的版本。
BouncyCastle FIPS 版本 2 已通过 FIPS 140-3 认证。因此,只要在符合 FIPS 140-3 的系统上使用 Keycloak,Keycloak 就可以符合 FIPS 140-3 标准。这可能是基于 RHEL 9 的系统,该系统本身符合 FIPS 140-3 标准。但请注意,基于 RHEL 8 的系统仅通过 FIPS 140-2 认证。
setOrCreateChild()
方法已从 JavaScript Admin Client 中移除
groups.setOrCreateChild()
方法已从基于 JavaScript 的 Admin Client 中移除。如果您仍在使用此方法,请改用 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 发行版 Universal Module Definition。这意味着该库不再作为全局变量公开,而必须作为 模块 导入。此更改符合现代 JavaScript 开发实践,并允许浏览器和构建工具之间更一致的体验,并且通常会产生更可预测的代码,副作用更少。
如果您正在使用诸如 Vite 或 Webpack 之类的 bundler,则没有任何变化,您将获得与以前相同的体验。如果您在浏览器中直接使用该库,则需要更新您的代码以将该库作为模块导入
<!-- 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>
您也可以选择使用 import map 使库的导入不那么冗长
<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.js
脚本的路径从服务器的 keycloak.json
文件自动加载。由于该库不再从服务器静态提供,因此此功能已被移除。您现在需要在构造 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 recommended 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
域提供的上下文。如果您在非安全上下文中使用该库,则需要更新您的开发环境以使用安全上下文。
迁移到 25.0.2
提高删除用户授权的性能
当客户端 scope 或完整的 realm 被删除时,关联的用户授权也应被移除。已在表 USER_CONSENT_CLIENT_SCOPE
上添加了一个新索引以提高性能。
请注意,如果表包含超过 300,000 个条目,则默认情况下,Keycloak 会在自动模式迁移期间跳过索引的创建,而是将 SQL 语句记录到控制台。这些语句必须在 Keycloak 启动后在数据库中手动运行。有关如何配置不同限制的详细信息,请查看升级指南。
迁移到 25.0.0
新的主机名选项
默认情况下支持主机名 v2 选项,因为旧的主机名选项已弃用,并将在后续版本中移除。默认情况下会激活新选项,因此 Keycloak 将无法识别旧选项。
必要的迁移列表
旧选项 | 新选项 |
---|---|
|
|
|
|
|
|
如您所见,hostname
和 hostname-admin
选项的 *-url
后缀已移除。选项 hostname
接受主机名和 URL,但 hostname-admin
现在仅接受完整 URL。
此外,无法单独设置 path
或 port
。您可以通过为 hostname
和 hostname-admin
选项提供完整 URL 来实现此目的。
如果端口不是 URL 的一部分,则会从传入的请求头动态解析端口。
除非 HTTPS 是 hostname
和 hostname-admin
URL 的一部分,否则不再强制使用 HTTPS。如果未指定,则使用的协议 (http/https
) 会从传入的请求动态解析。hostname-strict-https
选项已移除。
已移除的选项 |
---|
|
|
|
|
|
|
为了使用旧的主机名选项以获得更多迁移时间,请启用功能 hostname:v1 ,例如 features=hostname:v1 。请注意,hostname:v1 或 hostname: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 中,backchannel URL 是从请求头动态解析的。因此,为了实现所需的结果,您必须指定 hostname-strict-backchannel=true
。
对于主机名 v2,backchannel URL 已经与前端 URL 相同。为了从请求头动态解析它,您需要设置 hostname-backchannel-dynamic=true
并为 hostname
选项提供完整 URL。
有关更多详细信息和更全面的方案,请参阅配置主机名 (v2)。
security-admin-console
客户端重定向 URI
${authAdminUrl}
的处理在主机名 v1 中已更改。以前,对于主机名 v1,如果未设置 hostname-admin
或 hostname-admin-url
选项,则管理 URL 会从请求动态解析。对于主机名 v2,管理 URL 将默认设置为前端 URL。如果设置了 hostname
选项且 hostname-strict
为 true,则此更改将阻止具有备用主机名的重定向 URI 用于使用根 URL ${authAdminUrl}
的客户端。您应该考虑使用 hostname-admin
选项而不是重定向 URI,以允许单个备用主机名。应移除备用主机名重定向,因为 security-admin-console
客户端只需要根 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 Operator 为 HA 部署 Infinispan 指南。
启用此功能后,选项 spi-user-sessions-infinispan-offline-session-cache-entry-lifespan-override
和 spi-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 升级期间迁移用户会话,请执行以下步骤
-
停止所有正在运行的旧版 Keycloak 实例。
-
创建备份
-
创建 Keycloak 数据库的备份。
-
如果使用 JDBC 持久性,请创建该数据库的备份(如果您希望能够重试会话的迁移)。
-
如果使用外部 Infinispan,请创建其数据的备份(如果您希望能够重试会话的迁移)。
-
-
启动启用了持久用户会话功能的新 Keycloak 实例。
第一个启动节点将
-
将数据库迁移到模式版本 25。
-
将所有会话信息从远程 Infinispan 或为 Keycloak 嵌入式缓存配置的 JDBC 持久性复制到 Keycloak 的数据库。
数据将存储在表
offline_user_session
和offline_client_session
中,其中offline_flag
设置为false
。 -
清除缓存。
这包括清除外部 Infinispan 的缓存(如果使用了外部 Infinispan),以及清除 JDBC 持久性(如果使用了 JDBC 持久性)。
-
-
更新 Keycloak 的缓存配置 XML,用于缓存
sessions
和clientSessions
-
如果使用 JDBC 持久性,请删除 JDBC 持久性的配置。
-
如果远程 Infinispan 已在单站点设置中仅用于在 Keycloak 重启时保持用户会话,请删除这些缓存的远程 Infinispan 配置。
如果在多站点设置中使用远程 Infinispan,您可以通过配置内存中的条目数来降低外部 Infinispan 的资源消耗。使用使用 Infinispan Operator 为 HA 部署 Infinispan 指南中概述的设置。 -
-
滚动重启 Keycloak 以激活新的缓存配置 XML。
默认启用 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-enabled
和 http-metrics-slos
来启用默认直方图 bucket 或服务级别目标 (SLO) 的特定 bucket。有关直方图的更多信息,请阅读 Prometheus 文档中关于直方图 的内容,了解如何使用 http_server_requests_seconds_bucket
中提供的附加指标系列。
Argon2 密码哈希
在 Keycloak 24 版本中,我们的密码哈希算法发生了一项更改,导致 CPU 使用率增加。为了解决这个问题,我们为非 FIPS 环境选择了不同的默认哈希算法 Argon2,这使 CPU 使用率恢复到 Keycloak 24 版本之前的水平。
限制使用 HTTP 响应时的内存使用量
在某些场景下,例如 brokering,Keycloak 使用 HTTP 与外部服务器通信。为了避免在这些提供程序发送过多数据时发生拒绝服务,Keycloak 现在默认将响应限制为 10 MB。
用户可以通过设置提供程序配置选项 spi-connections-http-client-default-max-consumed-response-size
来配置此限制
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 个字母顶级域名结尾的 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
选项
选项 cache
、cache-stack
和 cache-config-file
不再是构建选项,它们只能在运行时指定。这消除了由于它们而执行构建阶段和重建镜像的需求。请注意,它们在 build
阶段不会被识别,因此您需要将它们从 build
阶段移除并添加到 runtime
阶段。如果您不将当前的缓存选项添加到 runtime
阶段,Keycloak 将回退到默认缓存设置。
kcadm 和 kcreg 更改
kcadm 和 kcreg 解析和处理选项和参数的方式已更改。来自用法错误、错误选项或参数的错误消息可能与以前的版本略有不同。此外,用法错误将具有退出代码 2 而不是 1。
移除自定义用户属性索引
当按用户属性搜索用户时,Keycloak 不再搜索用户属性名称强制小写比较。这意味着在搜索时,将使用 Keycloak 用户属性表上的本机索引。如果您已创建自己的基于 `lower(name)` 的索引来加速搜索,则现在可以将其移除。
新的默认客户端 scope basic
名为 basic
的新客户端 scope 已添加为 realm “default” 客户端 scope,因此将添加到所有新创建的 OIDC 客户端。客户端 scope 也会在迁移期间自动添加到所有现有的 OIDC 客户端。
此 scope 包含以下声明的预配置协议映射器
-
sub
(有关详细信息,请参见下面专门的部分) -
auth_time
这提供了额外的帮助,以减少轻量级访问令牌中的声明数量,同时也提供了配置始终自动添加的声明的机会。
如果您在某些 realm 中已经有一个名为 basic 的客户端 scope,那么新的客户端 scope basic 将不会添加到您的 realm 中,也不会添加到任何客户端。在这种特定情况下,迁移将被忽略。在这种情况下,您要么需要确保在迁移到此 Keycloak 版本之前将您的客户端 scope 重命名为 basic 以外的名称,要么您需要手动处理令牌中缺少的 sub 和 auth_time 声明(如果您需要它们),并且您可能需要手动将相应的协议映射器添加到您的某些客户端 scope。 |
移除 session_state
声明
session_state
声明包含与 sid
声明相同的值,现在已从所有令牌中移除,因为它不是 OpenID Connect 前端通道注销和 OpenID Connect 后端通道注销规范所要求的。session_state
声明仍然按照 OpenID Connect 会话管理规范存在于访问令牌响应中。
请注意,setSessionState()
方法也已从 IDToken
类中移除,取而代之的是 setSessionId()
方法,而 getSessionState()
方法现在已被弃用。
新的 Session State (session_state)
映射器也已包含在内,可以分配给客户端 scope(例如 basic
客户端 scope)以恢复到旧的行为。
如果使用旧版本的 JS 适配器,则也应通过使用如上所述的客户端 scope 来使用 Session State (session_state)
映射器。
sub
声明通过协议映射器添加到访问令牌
sub
声明以前总是添加到访问令牌中,现在默认添加,但使用新的 Subject (sub)
协议映射器。
Subject (sub)
映射器默认在 basic
客户端 scope 中配置。因此,升级到此版本后无需额外配置。
如果您正在使用 Pairwise subject identifier
映射器来映射访问令牌的 sub
声明,您可以考虑禁用或移除 Subject (sub)
映射器,但这并非严格必要,因为 Subject (sub)
协议映射器在 Pairwise subject identifier
映射器之前执行,因此 pairwise
值将覆盖 Subject (sub)
映射器添加的值。这也可能适用于其他自定义协议映射器实现,它们会覆盖 sub
声明,因为 Subject (sub)
映射器目前作为第一个协议映射器执行。
您可以仅对访问令牌、轻量级访问令牌和内省响应使用 Subject (sub)
映射器来配置 sub
声明。IDToken 和 Userinfo 始终包含 sub
声明。
该映射器对服务帐户无效,因为不存在用户会话,并且 sub
声明始终添加到访问令牌中。
Nonce 声明仅添加到 ID 令牌
nonce 声明现在仅添加到 ID 令牌,严格遵循 OpenID Connect Core 1.0 规范。正如规范中指出的,当在授权请求中发送相同的参数时,该声明在 ID 令牌中是强制性的。规范还建议在 刷新请求后不要添加 nonce
。以前,该声明在所有响应(包括刷新)中都设置为所有令牌(访问令牌、刷新令牌和 ID 令牌)。
软件中还包含一个新的 Nonce backwards compatible
映射器,可以分配给客户端 scope 以恢复到旧的行为。例如,JS 适配器在版本 24.0.0 中修复问题 #26651 之前,检查了所有令牌中返回的 nonce
声明。因此,如果使用旧版本的 JS 适配器,则应通过使用客户端 scope 将映射器添加到所需的客户端。
更改了与刷新令牌相关的事件的 userId
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 (session_state)
映射器 -
在使用早于 Keycloak 24 的 Keycloak Javascript 适配器的情况下,添加
Nonce backwards compatible
映射器
您可以将协议映射器直接添加到相应的客户端,或者添加到某些客户端 scope,您的客户端应用程序可以使用这些客户端 scope 来依赖旧版本的 Keycloak Javascript 适配器。有关更多详细信息,请参阅前面专门介绍 session_state
和 nonce
声明的部分。
默认 http-pool-max-threads
减少
如果未设置 http-pool-max-threads
,则默认值将为 50 或 4 x(可用处理器)中的较大值。以前,默认值为 200 或 8 x(可用处理器)中的较大值。由于减少了活动线程之间的上下文切换,因此对于大多数使用场景,减少任务线程数将导致略高的性能。
指标和健康端点的管理端口
/health
和 /metrics
端点可通过管理端口 9000
访问,默认情况下该端口已开启。这意味着这些端点不再暴露于标准的 Keycloak 端口 8080
和 8443
。
为了反映旧的行为,请使用属性 --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 实现取代。旧的提供程序已被弃用但未移除,以防它在某些现有 realm 中仍然可用。Keycloak 25.0.0 肯定会移除旧的提供程序及其关联的 linkedin-oauth
功能。从现在开始,默认的 LinkedIn
社交提供程序是唯一可用的选项。
改进了 findGrantedResources
和 findGrantedOwnerResources
查询的性能
当 RESOURCE_SERVER_RESOURCE
和 RESOURCE_SERVER_PERM_TICKET
表格包含超过 10 万条条目,并且用户被授予访问超过 1 千个资源的权限时,这些查询的性能很差。查询已得到简化,并为 requester
和 owner
列引入了新的索引。
新的索引都应用于 RESOURCE_SERVER_PERM_TICKET
表格。如果表格当前包含超过 30 万条条目,Keycloak 将默认在自动架构迁移期间跳过索引的创建,而是在迁移期间在控制台上记录 SQL 语句。在这种情况下,必须在 Keycloak 启动后在数据库中手动运行这些语句。
有关如何配置不同限制的详细信息,请参阅 升级指南。
从 AccessToken
、IDToken
和 JsonWebToken
类中移除已弃用的方法
以下方法已从 AccessToken
类中移除
-
expiration
。请改用exp
方法。 -
notBefore
。请改用nbf
方法。 -
issuedAt
。请改用iat
方法。
以下方法已从 IDToken
类中移除
-
getAuthTime
和setAuthTime
。请分别使用getAuth_time
和setAuth_time
方法。 -
notBefore
。请改用nbf
方法。 -
issuedAt
。请改用iat
方法。 -
setSessionState
。请改用setSessionId
方法(有关详细信息,请参阅上面关于session_state
声明的部分)
以下方法已从 JsonWebToken
类中移除
-
expiration
。请改用exp
方法。 -
notBefore
。请改用nbf
方法。 -
issuedAt
。请改用iat
方法。
您还应该预期令牌中未设置 exp
和 nbf
声明,因为它们是可选的。以前,这些声明被设置为值 0
,这没有多大意义,因为它们的值应该是有效的 NumericDate
。
方法 getExp
添加到 SingleUseObjectKeyModel
由于从 AccessToken
、IDToken
和 JsonWebToken
中移除了已弃用的方法,SingleUseObjectKeyModel
也进行了更改,以保持与过期值相关的方法名称的一致性。
之前的 getExpiration
方法现在已被弃用,您应该首选使用新引入的 getExp
方法,以避免 2038 年后的溢出。
PasswordHashProvider
上的方法 encode 已弃用
接口 org.keycloak.credential.hash.PasswordHashProvider
上的方法 String encode(String rawPassword, int iterations)
已弃用。该方法将在未来的 Keycloak 版本之一中移除。可能是 Keycloak 27 版本。
移除 CollectionUtil intersection 方法
方法 org.keycloak.common.util.CollectionUtil.intersection
已被移除。您应该在现有集合上使用 'java.util.Collection.retainAll' 代替。
Resteasy util 类已弃用
org.keycloak.common.util.Resteasy
已被弃用。您应该使用 org.keycloak.util.KeycloakSessionUtil
来获取 KeycloakSession
代替。
强烈建议避免使用创建自定义提供程序以外的其他方式获取 KeycloakSession
。
会话生存期和空闲计算的细微变化
在以前的版本中,当验证会话是否仍然有效时,会话最大生存期和空闲超时计算略有不同。现在,该验证使用与项目其余部分相同的代码。
如果会话正在使用记住我功能,则空闲超时和最大生存期是通用 SSO 和记住我配置值之间的最大值。
外部 Infinispan 要求
Keycloak 现在要求外部 Infinispan 部署的 Infinispan 服务器版本至少为 15.0.0。HA 指南中概述的多站点设置支持外部 Infinispan 部署。
Oracle 数据库驱动程序不包含在发行版中
Oracle 数据库 JDBC 驱动程序不再是 Keycloak 发行版的一部分。如果您希望使用 Oracle DB,您必须手动安装与您的特定环境兼容的 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
通过 Admin User API 更新用户时,不再支持对用户属性进行部分更新
通过 Admin User API 更新用户属性时,更新用户属性(包括根属性,如 username
、email
、firstName
和 lastName
)时,您无法执行部分更新。
如果您通过 Admin User API 更新用户属性,但未传递管理员具有写入权限的所有属性,则缺少的属性将被移除。另一方面,如果某个属性被标记为管理员只读,则不发送该属性不会将其移除。
有关用户配置文件设置的详细信息,请参阅 用户配置文件文档。
迁移到 24.0.3
org.keycloak.userprofile.UserProfileDecorator
接口的更改
为了正确支持 realm 中的多个用户存储提供程序,org.keycloak.userprofile.UserProfileDecorator
接口已更改。
decorateUserProfile
方法不再在首次解析用户配置文件配置(并缓存它)时调用,而是在每次通过用户配置文件提供程序管理用户时调用。因此,该方法更改了其约定为
List<AttributeMetadata> decorateUserProfile(String providerId, UserProfileMetadata metadata)
与之前的约定和行为不同,此方法仅为从中加载用户的用户存储提供程序调用。
迁移到 24.0.0
欢迎主题的更改
“welcome”主题已更新为使用新的布局,现在使用 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
。
帐户控制台主题自定义的更改
如果您之前扩展了现已弃用的版本 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
功能不再可用,因为用户配置文件假定为已启用。因此,用户配置文件已启用开关已从Realm 设置中移除,并替换为非托管属性。从以前的版本迁移时,行为如下:
-
对于用户配置文件已启用设置为开的部署,升级后非托管属性将设置为关。因此,仅允许用户配置文件显式支持的用户属性。
-
对于用户配置文件已启用设置为关的部署(这也是禁用
declarative-user-profile
功能的部署的默认设置,而这又是默认设置),升级后非托管属性将设置为开。因此,行为应与以前禁用用户配置文件的版本基本相同。属性选项卡将保留在管理控制台的用户详细信息部分中。此外,只要特定的自定义主题支持,用户现在可以通过 UI 页面(例如注册页面和更新配置文件页面)设置任意属性。自定义主题也应像以前一样工作。但是,请考虑更新您的主题以使用用户配置文件,甚至在需要添加自定义属性时移除您的自定义主题。请参阅后续关于主题的部分。此外,请考虑将非托管属性切换为关,或仅为管理员启用此开关,以便您可以主要依赖于使用托管属性。
有关非托管属性的详细信息,请参阅 用户配置文件文档。
默认验证
默认用户配置文件配置带有一组基本预定义字段的默认验证。当默认禁用 declarative-user-profile
功能时,这些验证在以前的版本中不存在。如果由于向后兼容性而遇到问题,您可以根据需要更改默认验证器。默认验证器如下:
-
username
、email
、firstName
和lastName
属性的最大长度为 255 个字符。由于数据库约束,这些验证也间接地存在于以前的版本中,表格USER_ENTITY
中这些字段的最大长度为 255 个字符。但是,当使用用户存储提供程序时,以前可能可以使用更长的值。 -
username
属性的最小长度为三个字符。默认情况下,用户名还具有username-prohibited-characters
和up-username-not-idn-homograph
验证器,这些验证器在以前的版本中不存在。有关这些属性的详细信息,请参阅 用户配置文件文档的验证部分。请注意,除非您启用了 realm 开关Edit username enabled
,否则默认情况下用户名是不可编辑的。此更改意味着用户名不正确的现有用户仍然可以工作,并且不会强制他们更新用户名。但是,新用户将被强制在注册或通过管理 REST API 创建时使用正确的用户名。 -
firstName
和lastName
属性现在具有person-name-prohibited-characters
验证器,这在之前的版本中是没有的。 有关这些属性的详细信息,请参阅用户配置文件文档的验证部分。 请注意,默认情况下名字和姓氏都是可编辑的,因此,如果用户从以前的版本中已经有了不正确的名字/姓氏,则在更新其用户配置文件时,将被强制更新它们。
具有特殊字符的用户属性名称
在以前的版本中,您可以创建具有诸如 some:attribute
或 some/attribute
等属性名称的用户。 用户配置文件有意不允许您在用户配置文件配置中创建具有如此特殊名称的属性。 因此,您可能需要为您的 realm 配置非托管属性
,并为管理员(理想情况下)或最终用户(如果确实需要)启用非托管属性。 尽管强烈建议避免使用此类属性名称。
默认启用“验证配置文件”必需操作
新的 realm 默认启用 verify-profile
必需操作。 但是,当您从以前的版本迁移时,您现有的 realm 将具有与之前相同的 verify-profile
操作状态,这通常意味着禁用,因为它在以前的版本中默认是禁用的。 有关此必需操作的详细信息,请参阅用户配置文件文档。
用户配置文件 SPI 的重大更改
如果您在扩展程序中使用用户配置文件 SPI,您可能会受到此版本中引入的 API 更改的影响。
org.keycloak.userprofile.Attributes
接口包含以下更改
-
方法
getValues
已重命名为get
,使其与常规 JavaMap
中的相同操作更加一致 -
方法
isRootAttribute
已移动到实用程序类org.keycloak.userprofile.UserProfileUtil.isRootAttribute
-
方法
getFirstValue
已重命名为getFirst
,使其不那么冗长 -
方法
getReadable(boolean)
已被删除,现在只要具有读取权限,就会返回所有属性(包括根属性)。
Freemarker 模板的更改,以基于用户配置文件和 realm 呈现页面
在此版本中,以下模板已更新,以便可以根据为 realm 设置的用户配置文件配置动态呈现属性
-
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.ftl
和 register.ftl
。
通过代理首次登录时更新配置文件页面的新 Freemarker 模板
在此版本中,当用户首次通过代理进行身份验证时,服务器将使用 idp-review-user-profile.ftl
模板呈现更新配置文件页面。
在以前的版本中,在首次代理登录流程期间用于更新配置文件的模板是 login-update-profile.ftl
,与用户向 realm 进行身份验证时更新配置文件所使用的模板相同。
通过为每个流程使用单独的模板,可以更清楚地区分模板实际用于哪个流程,而不是共享同一个模板,并可能引入意外的更改和行为,而这些更改和行为应该只影响特定流程的页面。
如果您对 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 的其他部分。
例如,如果 attestation conveyance 配置为 Direct 验证,则 webauthn 注册可能会失败。 以前,如果未配置信任库提供程序,则不会验证传入的证书。 但现在始终执行此验证。 注册失败,并显示 invalid cert path
错误,因为 dongle 发送的证书链不受 Keycloak 的信任。 身份验证器的证书颁发机构需要存在于信任库提供程序中,才能正确执行 attestation。
已弃用的 --proxy
选项
--proxy
选项已被弃用,并将在未来的版本中删除。 下表解释了已弃用的选项如何映射到受支持的选项。
已弃用的用法 | 新的用法 |
---|---|
|
|
|
|
|
|
|
|
|
|
为了加强安全性,--proxy-headers 选项不允许同时选择 forwarded 和 xforwarded 值(就像以前的 --proxy edge 和 --proxy reencrypt 的情况一样)。 |
当使用 proxy headers 选项时,请确保您的反向代理正确设置并覆盖 Forwarded 或 X-Forwarded-* 标头。 要设置这些标头,请查阅您的反向代理的文档。 配置错误将使 Keycloak 暴露于安全漏洞。 |
当使用 Operator 时,您也可以设置 proxy headers
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
proxy:
headers: forwarded|xforwarded
如果未指定 proxy.headers 字段,则 Operator 会回退到以前的行为,默认情况下隐式设置 proxy=passthrough 。 这会导致服务器日志中出现弃用警告。 此回退将在未来的版本中删除。 |
Admin API 和 Account 上下文中用户表示形式的更改
org.keycloak.representations.idm.UserRepresentation
和 org.keycloak.representations.account.UserRepresentation
表示类都已更改,以便在分别向 Admin 和 Account API 获取或发送表示形式有效负载时,根用户属性(例如 username
、email
、firstName
、lastName
和 locale
)具有一致的表示形式。
username
、email
、firstName
、lastName
和 locale
属性已移动到新的 org.keycloak.representations.idm.AbstractUserRepresentation
基类。
此外,getAttributes
方法的目标是仅表示自定义属性,因此您不应期望在此方法返回的 map 中找到任何根属性。 此方法主要针对客户端在更新或获取给定用户的任何自定义属性时使用。
为了解析包括根属性在内的所有属性,添加了一个新的 getRawAttributes
方法,以便生成的 map 也包括根属性。 但是,此方法不能从表示形式有效负载中使用,其目标是在服务器管理用户配置文件时使用。
顺序加载离线会话和远程会话
从该版本开始,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_ATTRIBUTE
和 FED_USER_ATTRIBUTE
上添加了新索引。 如果这些表包含超过 300000 个条目,则默认情况下 Keycloak 将在自动模式迁移期间跳过索引创建,而是在迁移期间将 SQL 语句记录到控制台上,以便在 Keycloak 启动后手动应用。 有关如何配置不同限制的详细信息,请参阅升级指南。
新添加的索引 USER_ATTR_LONG_VALUES_LOWER_CASE 和 FED_USER_ATTR_LONG_VALUES_LOWER_CASE 可能会超出 Oracle 设置的最大 30 个字符的限制,如果数据库在兼容模式下运行。 自 Oracle 版本 12.2 以来,支持更长的索引名称。 |
Admin send-verify-email API 现在使用相同的电子邮件验证模板
PUT /admin/realms/{realm-name}/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@example.org.
如果您已自定义 executeActions.ftl
模板以修改用户如何使用此 API 验证其电子邮件,请确保将您的修改转移到新模板。
将引入一个名为 lifespan
的新参数,以允许覆盖默认的生存期值(12 小时)。
如果您喜欢以前的行为,请按如下方式使用 execute-actions-email
API。
PUT /admin/realms/{realm-name}/users/{id}/execute-actions-email ["VERIFY_EMAIL"]
删除 SAML 加密的已弃用模式
版本 21 中引入的 SAML 加密兼容模式现已删除。 系统属性 keycloak.saml.deprecated.encryption
不再由服务器管理。 仍使用旧签名密钥进行加密的客户端应从新的 IDP 配置元数据中更新它。
密码哈希的更改
在此版本中,我们调整了密码哈希默认值,以匹配 OWASP 密码存储建议。
作为此更改的一部分,默认密码哈希提供程序已从 pbkdf2-sha256
更改为 pbkdf2-sha512
。 此外,基于 pbkdf2
的密码哈希算法的默认哈希迭代次数也发生了如下更改
提供程序 ID | 算法 | 旧迭代次数 | 新迭代次数 |
---|---|---|---|
|
|
20.000 |
1.300.000 |
|
|
27.500 |
600.000 |
|
|
30.000 |
210.000 |
如果 realm 没有使用 hashAlgorithm
和 hashIterations
显式配置密码策略,则新配置将在下一次基于密码的登录时生效,或者在创建或更新用户密码时生效。
新密码哈希配置的性能
在配备 Intel i9-8950HK CPU (12) @ 4.800GHz 的机器上进行的测试,得出了哈希 1000 个密码的以下平均时间差异(3 次运行的平均值)。 请注意,由于运行时较长,因此使用较少的密码计算了 PBKDF2WithHmacSHA1
的平均持续时间。
提供程序 ID | 算法 | 旧持续时间 | 新持续时间 | 差异 |
---|---|---|---|---|
|
|
122 毫秒 |
3.114 毫秒 |
+2.992 毫秒 |
|
|
20 毫秒 |
451 毫秒 |
+431 毫秒 |
|
|
33 毫秒 |
224 毫秒 |
+191 毫秒 |
pbkdf2
提供程序的用户可能需要显式减少哈希迭代次数以重新获得可接受的性能。 这可以通过在 realm 的密码策略中显式配置哈希迭代次数来完成。
预计总体 CPU 使用率增加和临时数据库活动增加
Keycloak 高可用性指南中 CPU 和内存资源调整大小的概念已更新,以反映新的哈希默认值。 在我们的测试中,每次基于密码的登录的 CPU 使用率增加了五倍,其中包括更改的密码哈希和未更改的 TLS 连接处理。 由于 Keycloak 的其他活动(如刷新访问令牌和客户端凭据授权)的平均效应,总体 CPU 增加应在两到三倍左右。 然而,这取决于安装的独特工作负载。
升级后,在基于密码的登录期间,用户的密码将使用新的哈希算法和哈希迭代作为一次性活动重新哈希,并在数据库中更新。 由于这会从 Keycloak 的内部缓存中清除用户,您还将看到数据库级别的读取活动增加。 随着越来越多的用户密码被重新哈希,这种增加的数据库活动将随着时间的推移而减少。
Operator 引用的资源轮询
通过 Keycloak CR 引用的 Secret 和 ConfigMap 现在将轮询更改,而不是通过 api 服务器监视。 检测到更改可能需要大约 1 分钟。
这样做是为了不需要对这些资源进行标签操作。 升级后,如果任何 Secret 仍然具有 operator.keycloak.org/component 标签,则可以删除或忽略它。
重命名 JPA 提供程序配置选项以进行迁移
删除 Map Store 后,以下配置选项已重命名
-
spi-connections-jpa-legacy-initialize-empty
为spi-connections-jpa-quarkus-initialize-empty
-
spi-connections-jpa-legacy-migration-export
为spi-connections-jpa-quarkus-migration-export
-
spi-connections-jpa-legacy-migration-strategy
为spi-connections-jpa-quarkus-migration-strategy
重命名模型模块
删除 Map Store 后,以下模块已重命名
-
org.keycloak:keycloak-model-legacy-private
为org.keycloak:keycloak-model-storage-private
-
org.keycloak:keycloak-model-legacy-services
为org.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 中的描述编写自定义事件侦听器。
Keycloak CR 资源选项
当在 Keycloak CR 和 KeycloakRealmImport CR 中未指定 resources
选项时,将使用默认值。 Keycloak 部署和 realm 导入 Job 的默认 requests
内存设置为 1700MiB
,limits
内存设置为 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 本身使用的 JWT,例如刷新令牌或操作令牌)的算法正在从 HS256
更改为更安全的 HS512
。 现在为 realm 添加了一个名为 hmac-generated-hs512
的新密钥提供程序。 请注意,在迁移的 realm 中,旧的 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 事件消息的更改
由于问题 #25078,jboss-logging
消息值现在被引用(默认情况下为字符 "
)并经过清理以防止任何换行符。 提供程序中有两个新选项(spi-events-listener-jboss-logging-sanitize
和 spi-events-listener-jboss-logging-quotes
)允许您自定义新行为。 例如,要避免清理和引用,服务器可以按以下方式启动
./kc.sh start --spi-events-listener-jboss-logging-sanitize=false --spi-events-listener-jboss-logging-quotes=none ...
有关选项的更多信息,请参阅所有提供程序配置指南。
迁移到 23.0.2
客户端的有效重定向 URI 始终使用精确字符串匹配进行比较
版本 1.8.0 在将重定向 URI 与客户端指定的有效重定向进行比较时,引入了主机名和 scheme 的小写。 不幸的是,它并非在所有协议中都完全有效,例如,主机对于 http
是小写的,但对于 https
不是。 由于 OAuth 2.0 安全最佳实践 建议使用精确字符串匹配来比较 URI,因此 Keycloak 将遵循该建议,并且从现在开始,即使对于主机名和 scheme,有效重定向也使用精确大小写进行比较。
对于依赖旧行为的 realm,其客户端的有效重定向 URI 现在应为每个应由服务器识别的 URI 保留单独的条目。
尽管在配置客户端时引入了更多步骤和冗长性,但新行为实现了更安全的部署,因为基于模式的检查通常是安全问题的原因。 这些问题是由于它们的实现方式以及它们的配置方式造成的。
Operator -secrets-store Secret
旧版本的 Operator 创建了一个 Secret 来跟踪监视的 Secret。 新版本的 Operator 不再使用 -secrets-store Secret,因此可以删除它。
如果您使用的是 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 Secret,或者升级到 23.0.2 版本,此问题已在 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 和客户端角色映射器映射的声明的值格式的更改
在本版本之前,当 Multivalued
设置禁用时,realm(User Realm Role
)和客户端(User Client Role
)协议映射器都会映射字符串化的 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://#:5432/keycloak?ssl=false&connectTimeout=30\"" --db-password keycloak --hostname localhost
使用单次转义
bin/kc.sh start --db postgres --db-username keycloak --db-url "jdbc:postgresql://#: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 中显示为 Profile Validation
)已从代码库和所有身份验证流程中移除。默认情况下,它位于每个 realm 的内置注册流程中。用户属性的验证以及包括所有用户属性的用户创建都由 RegistrationUserCreation
表单操作处理,因此不再需要 RegistrationProfile
。通常,与此更改无关,无需采取进一步操作,除非您在自己的提供程序中使用了 RegistrationProfile
类。
GroupProvider
更改
添加了一个新方法,允许搜索和分页顶级组。如果您实现了此接口,则需要实现以下方法
Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm,
String search,
Boolean exact,
Integer firstResult,
Integer maxResults)
GroupRepresentation
更改
-
添加了新字段
subGroupCount
,用于通知客户端任何给定组上有多少个子组 -
subGroups
列表现在仅在请求层次结构数据的查询中填充 -
此字段从“自下而上”填充,因此不能依靠它来获取组的所有子组。使用
GroupProvider
或从GET {keycloak server}/realms/{realm-name}/groups/{group_id}/children
请求子组
组管理 API 的新端点
添加了端点 GET {keycloak server}/realms/{realm-name}/groups/{group_id}/children
,作为获取支持分页的特定组的子组的一种方式
RESTEasy Reactive
依赖 RESTEasy Classic 不再是一种选择,因为它不再可用。对于依赖 RESTEasy Classic 和 org.jboss.resteasy.spi.*
相关包的 SPI 和代码,将需要进行迁移。
部分导出需要 manage-realm 权限
端点 POST {keycloak server}/realms/{realm-name}/partial-export
和管理控制台中的相应操作现在需要 manage-realm
权限才能执行,而不是 view-realm
权限。此端点将 realm 配置导出到 JSON 文件中,新的权限更合适。参数 exportGroupsAndRoles
和 exportClients
分别将 realm 组/角色和客户端包含在导出中,继续管理相同的权限(query-groups
和 view-clients
)。
移除用于修剪事件详细信息长度的选项
自此版本起,Keycloak 支持 EventEntity
details 列的长值。因此,它不再支持修剪事件详细信息长度的选项 --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.2
从客户端高级设置组合框中移除了“永不过期”选项
现在已从客户端选项卡“高级设置”的所有组合框中移除了 永不过期
选项。此选项具有误导性,因为不同的生存时间或空闲超时时间永远不是无限的,而是受常规用户会话或 realm 值的限制。因此,移除了此选项,转而使用其他两个剩余选项:从 realm 设置继承
(客户端使用常规 realm 超时时间)和 在以下时间过期
(为客户端覆盖该值)。在内部,永不过期
由 -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.security
、javax.net
、javax.crypto
等。
您的自定义扩展、提供程序或 JPA 实体可能会受到这些更改的影响。
升级到 Quarkus 3
Keycloak 已升级到 Quarkus Java 框架的第 3 版。Quarkus 3 延续了通过快速发展和使用最新技术提供尖端用户体验来推动 Java 开发的传统。它继续提高整体性能和效率。
Quarkus 3 基于 Jakarta EE 10,与 Keycloak 相同,在它们之间创建了平滑的互操作性。此外,它还包含与 Jakarta EE 10 Core Profile 对齐的 Eclipse MicroProfile 6。Quarkus 3 升级的核心部分是内置支持 JPA 3.1 和 Hibernate ORM 6。
升级到 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');
}
导出和导入执行自动构建
在以前的版本中,export
和 import
命令需要首先运行 build
命令。从本版本开始,如果构建时配置已更改,则 export
和 import
命令将执行 Keycloak 的自动重建。
当迁移首先运行 build
命令的现有脚本时,通过向 export
和 import
命令添加 --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
命令。
在以前的版本中,export
和 import
命令仅允许在配置文件或环境变量中使用运行时参数,例如数据库 URL。从本版本开始,这些运行时参数现在也可以在命令行中使用。使用 --help
选项查找有关支持的参数的信息。
重命名了 Keycloak Admin 客户端工件
在升级到 Jakarta EE 后,Keycloak Admin 客户端的工件已重命名为更具描述性的名称,并考虑了长期可维护性。我们仍然提供两个单独的 Keycloak Admin 客户端,一个支持 Jakarta EE,另一个支持 Java EE。
我们停止发布 org.keycloak:keycloak-admin-client-jakarta
工件。用于 Keycloak Admin 客户端的默认工件(支持 Jakarta EE)是 org.keycloak:keycloak-admin-client
(自 22.0.0 版本起)。
新的支持 Java EE 的工件是 org.keycloak:keycloak-admin-client-jee
。
直通代理模式更改
Keycloak 的代理配置设置对于 直通 模式不再解析请求中的 HTTP 转发标头,因为当代理以直通模式转发 HTTPS 连接时,代理无法添加、删除或更新 HTTP 标头。
希望解析客户端请求中的 HTTP 标头的安装应使用 边缘 或 重新加密 设置。
有关详细信息,请参见 使用反向代理。
所有主题的统一回退消息解析
当您使用 realm 本地化消息时,此更改可能只会影响您。
在此版本之前,当使用 realm 本地化消息时,跨主题的回退消息解析是不一致的。更多信息可以在以下 issue 中找到。
现在,所有主题的实现都已统一。通常,最具体的匹配语言标签的消息具有最高优先级。如果同时存在 realm 本地化消息和主题 i18n 消息,则 realm 本地化消息具有更高的优先级。总结来说,消息的优先级如下(RL = realm 本地化,T = 主题 i18n 文件):RL <变体> > T <变体> > RL <区域> > T <区域> > RL <语言> > T <语言> > RL en > T en
。
可能可以通过一个示例更好地解释这一点:当请求变体 de-CH-1996
并且存在该变体的 realm 本地化消息时,将使用此消息。如果不存在此类 realm 本地化消息,则会在主题 i18n 文件中搜索该变体的相应消息。如果不存在此类消息,则会搜索区域(de-CH
)的 realm 本地化消息。如果不存在此类 realm 本地化消息,则会在主题 i18n 文件中搜索该区域的消息。如果仍然找不到消息,则会搜索语言(de
)的 realm 本地化消息。如果没有匹配的 realm 本地化消息,则会在主题 i18n 文件中搜索该语言的消息。作为最后的后备方案,将使用英语 (en
) 翻译:首先,将搜索英语 realm 本地化 - 如果未找到,则会在主题 i18n 文件中搜索英语消息。
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-redirect
、basic-auth
和 basic-auth-otp
已被移除。http challenge
身份验证流程也旨在用于 Openshift 集成,因此它已与其他相关功能一起移除,如上所述。身份验证器实现已移动到上一段中描述的 Openshift 扩展。
如果您将 http challenge
流程用作 realm 流程,或者用作任何身份提供程序的 First Broker Login
或 Post Broker Login
流程,则无法进行迁移。请务必更新您的 realm 配置以消除对 http challenge
流程的使用,然后再进行迁移。如果您将 http challenge
流程用作任何客户端的 Authentication Flow Binding Override
,则迁移将完成,但您将无法再登录到该客户端。迁移后,您需要重新创建流程并更新客户端的配置以使用新的/不同的 Json 流程。
移除第三方依赖项
移除 openshift-integration 使我们能够从 Keycloak 发行版中移除一些第三方依赖项。这包括 openshift-rest-client
、okio-jvm
、okhttp
、commons-lang
、commons-compress
、jboss-dmr
和 kotlin-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
您需要在打包自定义提供程序的 JAR 文件中添加一个空的 META-INF/beans.xml
文件。否则,它们在运行时不会被服务器识别。
如果您正在使用 RealmResourceSPI
或 AdminRealmResourceSpi
,您可以选择在 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)
已被移除。 -
为流式处理工作添加的接口已被移除。例如
RoleMapperModel.Streams
和类似的接口。 -
联合存储提供程序类中的
Streams
接口已被弃用。 -
KeycloakModelUtils#getClientScopeMappings
已被移除。 -
KeycloakSession
中已弃用的方法已被移除。 -
UserQueryProvider#getUsersStream
方法已被移除。
多个 Keycloak 实例
可以在同一命名空间中创建多个 Keycloak CR,并且它们将由 operator 独立管理。为了实现这一点,必须重新创建旧版本 operator 创建的 StatefulSets。当 operator 升级时,这将自动发生,并导致少量停机时间。
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
默认情况下,Classpath 上提供了 Javascript 引擎
在之前的版本中,当 Keycloak 在 Java 17 上与 Javascript 提供程序(脚本身份验证器、Javascript 授权策略或用于 OIDC 和 SAML 客户端的脚本协议映射器)一起使用时,需要将 javascript 引擎复制到发行版中。现在不再需要这样做,因为 Nashorn javascript 引擎默认在 Keycloak 服务器中可用。当您部署脚本提供程序时,建议不要将 nashorn 脚本引擎及其依赖项复制到 Keycloak 发行版中。
服务帐户客户端的默认客户端 ID 映射器更改
服务帐户客户端
的默认 客户端 ID
映射器已更改。Token Claim Name
字段值已从 clientId
更改为 client_id
。client_id
claim 符合 OAuth2 规范
clientId
userSession 注释仍然存在。
Keycloak JS 适配器必须使用 new
运算符实例化
从历史上看,可以通过直接调用 Keycloak()
函数来创建 Keycloak JS 适配器的实例
const keycloak = Keycloak();
为了使其与 JavaScript 世界的现代约定保持一致,可以使用 new
运算符 来创建实例
const keycloak = new Keycloak();
函数式构造函数已被弃用一段时间,但从这个版本开始,当使用它时,我们将主动记录弃用消息。这种构造函数风格将在未来的版本中移除,因此请确保迁移您的代码以使用 new
运算符。
迁移到 21.0.0
Keycloak 使用 Micrometer 进行指标监控
Keycloak 提供了一个可选的指标端点,该端点以 Prometheus 格式导出指标。在此版本中,提供此数据的实现从 SmallRye 切换到 Micrometer,Micrometer 是 Quarkus 推荐的指标库。
由于此更改,指标已被重命名。下表显示了一些示例。
建议在升级之前和之后查看端点返回的所有指标,并更新仪表板和警报中的用法。
旧指标名称 | 新指标名称 |
---|---|
|
|
|
|
|
|
|
|
SAML 已弃用的 RSA_SHA1 和 DSA_SHA1 算法
算法 RSA_SHA1
和 DSA_SHA1
在 SAML 适配器、客户端和身份提供程序上可以配置为 签名算法
,已被弃用。我们建议使用基于 SHA256
或 SHA512
的更安全的替代方案。此外,在 Java 17 或更高版本上,使用这些算法验证已签名的 SAML 文档或断言的签名不起作用。如果您使用此算法,并且使用您的 SAML 文档的另一方在 Java 17 或更高版本上运行,则签名验证将不起作用。
可能的解决方法是从文件 $JAVA_HOME/conf/security/java.security
中配置的属性 jdk.xml.dsig.secureValidationPolicy
的“不允许的算法”列表中删除诸如 http://www.w3.org/2000/09/xmldsig#rsa-sha1
或 http://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
H2 版本更新
Keycloak 出于开发目的附带了 H2 数据库驱动程序。因为它仅用于开发目的,所以绝不应在生产环境中使用。
在此版本中,H2 驱动程序已从 1.x 版本升级到 2.x 版本。此更改可能需要更改 H2 JDBC URL 或迁移现有 Keycloak 设置中的 H2 数据库文件。
H2 JDBC URL 的更改
为了使 Keycloak 能够在 H2 2.x 版本上使用其 JPA 旧版存储运行,JDBC URL 需要属性 NON_KEYWORDS=VALUE
。
在 Keycloak 初始化 H2 而不使用额外参数的设置中,Keycloak 将自动附加该属性。这是开发设置的默认设置。
如果在命令行或配置文件中提供了 H2 JDBC URL,并且它已经在 JDBC URL 中包含 NON_KEYWORDS=
属性,则需要使用 VALUE
关键字修改此属性。
如果 H2 数据库的连接工厂在 Keycloak 外部初始化,则该初始化需要注意添加 NON_KEYWORDS
属性。
有关详细信息,请参阅 H2 文档 关于 NON_KEYWORDS
属性。
H2 数据库文件的升级
使用 H2 1.x 版本创建的 H2 数据库基本文件不应与 2.x 版本一起使用。
清除现有的 H2 数据库文件以使用空数据库启动,使用 Keycloak 的导出和导入功能导出和导入 realm,或参考 H2 数据库项目网站上的迁移说明,了解有关如何迁移 H2 数据库内容的详细信息。
新版本 Keycloak Operator 中的重大更改
为了使用最新版本的 Keycloak Operator,需要手动重新安装和升级您的 CR。没有自动迁移。 |
此版本包含 Keycloak CR 中的以下重大更改
serverConfiguration 自由格式字段已重命名
从现在开始,它被称为 additionalOptions
。此决策背后的想法是使其更符合 Keycloak Quarkus 发行版,并实现/保持命名一致性。serverConfiguration
仍然可以用于配置在 Keycloak 自定义资源 (CR) 中没有声明替代方案的选项。服务提供程序可以是这种用法的很好示例。
Ingress 选项已改进
过去,它曾经通过 disableDefaultIngress
属性定义。我们决定稍微澄清一下,因此从现在开始,您可以使用以下结构来控制您的 ingress 设置
spec:
...
ingress:
enabled: false
HTTP 选项已添加
与 ingress 类似,您可以通过更好的结构化方式定义多个 HTTP 选项
spec:
...
http:
httpEnabled: true
httpPort: 80
httpsPort: 443
tlsSecret: my-tls-secret
数据提供程序和模型中已弃用的方法已被移除
在 Keycloak 15 之前,我们清理了提供程序和模型接口,其中我们弃用了一些方法。这些方法的 Javadoc 包含相应的替换方法(请参阅 Keycloak 19 版本的 Javadoc)。在此版本中,这些方法已被移除。以下是所有已更改类的列表。
弃用和移除方法的最常见模式如下。
-
流式处理 - 接口现在仅包含基于 Stream 的方法。
例如,在
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
-
所有更改都链接到以下 issue。
迁移到 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 Admin API 将脚本上传到服务器。
从现在开始,此功能被禁用,用户应直接将脚本部署到服务器。此行为与其他基于脚本的提供程序保持一致。有关更多详细信息,请查看 JavaScript 提供程序。
UserInfo 端点更改
- 错误响应更改
-
UserInfo 端点现在返回完全符合 RFC 6750(OAuth 2.0 授权框架:Bearer 令牌使用)的错误响应。错误代码和描述(如果可用)作为
WWW-Authenticate
挑战属性而不是 JSON 对象字段提供。响应将如下所示,具体取决于错误情况-
如果未提供访问令牌
401 Unauthorized WWW-Authenticate: Bearer realm="myrealm"
-
如果同时使用多种方法来提供访问令牌(例如,Authorization 标头 + 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"
-
如果无法解析 UserInfo 响应签名/加密的加密密钥
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
(见上文)。 -
UserInfo 现在检查用户状态,如果用户被禁用,则返回
invalid_token
响应。
-
迁移到 19.0.0
新的管理控制台现在是默认控制台
新的管理控制台现在是 Keycloak 中的默认控制台。如果您无法开始使用新的管理控制台,可以继续使用旧的管理控制台,方法是禁用新的控制台,例如运行
bin/kc.sh start-dev --features-disabled=admin2
继续使用旧的管理控制台的另一种方法是将 master realm 或任何其他 realm 的主题设置为 keycloak
。
由于新的管理控制台与旧的管理控制台显着不同,现在基于 React 并使用较新版本的 PatternFly,因此任何自定义主题都极有可能必须从头开始重新实现。要为新的管理控制台创建自定义主题,该主题应扩展 keycloak.v2
而不是 keycloak
。
如果您已明确将 master 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 包,请务必切换到 日志记录指南 中受支持的配置选项,并从 providers
文件夹中删除您的 jar 包。
影响开发人员的更改
Keycloak 正在进行大规模重构,这会影响现有代码。其中一些更改需要更新现有代码。这些更改将在下面更详细地描述。
更改的理由
Keycloak 有一些限制;例如,升级 Keycloak 集群需要停机。为了解决这些限制,已经启动了深入的重构。
此版本中的更改主要与存储重构和新存储(称为 map storage)的准备工作有关。此存储最终将取代当前的存储,在本版本中当前的存储将被称为旧式存储。旧式存储在 Keycloak 中仍然可用几个版本。
新存储对服务层和存储层之间的职责进行了严格分离。因此,服务层对对象来源的可见性将受到限制,因此它将无法区分缓存对象或非缓存对象,或者源自本地或联合存储的对象。
用户存储 SPI 将被弃用。它将在几个版本内继续受到支持,但最终将被 Map Storage SPI 取代,Map Storage SPI 将能够为任何已识别的领域(例如用户、角色、客户端或组)创建自定义存储。
依赖于旧式存储中服务可用的详细程度的扩展将需要进行调整,以便在旧式存储的完整弃用期内保留此能力。以下部分描述了如何完成此调整。
使用旧式存储和 map 存储是互斥的;一个存储不能在另一个存储处于活动状态时使用。
模块结构的更改
作为引入新存储功能的一部分,KeycloakSession
中围绕存储功能的几个公共 API 已被整合,一些已被弃用,将在接下来的版本之一中删除。引入了三个新模块,并且来自 server-spi
、server-spi-private
和 services
模块的面向数据的代码已移动到那里
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()
。这种情况可能会让开发人员感到困惑,他们必须了解每个方法的确切含义,并且依赖于当前的存储布局。新存储不区分联合存储和本地存储。
出于这些原因,KeycloakSession
中仅保留 users()
方法,并且应替换上面列出的所有其他调用。其余方法已被弃用,最终将被删除。相同的弃用模式适用于其他对象区域的方法,例如 clients()
或 groups()
。所有以 *StorageManager()
和 *LocalStorage()
结尾的方法在被调用时现在都会抛出异常,因为在新存储中没有直接的替代方法。下一节描述如何在旧存储中使用旧 API 时将这些调用迁移到新 API 或使用旧 API。
KeycloakSession 中已弃用的方法将在未来的版本中删除。keycloak-model-legacy-*
模块将可用更长时间,最终将被删除。
迁移不依赖于旧式存储的现有提供程序
如果现有提供程序不调用已弃用的方法,则无需迁移,对于大多数提供程序来说应该是这种情况。
如果提供程序使用已弃用的方法,但不依赖于本地存储与非本地存储,则将调用从现在已弃用的 userLocalStorage()
更改为方法 users()
是最佳选择。请注意,这里的语义发生了变化,因为如果本地设置中启用了缓存,则新方法会涉及缓存。
session.userLocalStorage();
session.users();
迁移依赖于旧式存储的现有提供程序
在极少数情况下,当自定义提供程序需要区分特定提供程序的模式时,可以使用 LegacyStoreManagers
数据存储提供程序来访问已弃用的对象。仅当旧式模块是部署的一部分时,此选项才可用。
session.userLocalStorage();
((LegacyDatastoreProvider) session.getProvider(DatastoreProvider.class)).userLocalStorage();
一些与用户存储相关的 API 为了方便起见已包装在 org.keycloak.storage.UserStorageUtil
中。
RealmModel
的更改
方法 `getUserStorageProviders`、`getUserStorageProvidersStream`、`getClientStorageProviders`、`getClientStorageProvidersStream`、`getRoleStorageProviders` 和 `getRoleStorageProvidersStream` 已被删除。依赖于这些方法并在启用旧式存储的情况下运行的代码应按如下方式转换实例
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
。虽然在使用旧式存储进行缓存时可能需要此类调用,但在使用新的 map 存储时则不需要,因为新的 map 存储透明地处理缓存。
// session.userCache() might return null, null-check omitted for brevity.
session.userCache().evict(realm, user);
// session.getProvider(UserCache.class) might return null, null-check omitted for brevity.
session.getProvider(UserCache.class).evict(realm, user);
要触发 realm 的失效,请考虑触发事件,而不是使用 UserCache
API
UserCache cache = session.getProvider(UserCache.class);
if (cache != null) cache.clear();
session.invalidate(InvalidationHandler.ObjectType.REALM, realm.getId());
用户的凭据管理
用户的凭据以前使用 session.userCredentialManager().method(realm, user, ...)
进行管理。新的方法是利用 user.credentialManager().method(...)
。这种形式使凭据功能更接近用户的 API,并且不依赖于事先了解用户凭据在 realm 和存储中的位置。
旧的 API 已被弃用,并且仅在部署中启用旧式存储时才有效。新的 API 将适用于旧存储和新存储。
session.userCredentialManager().createCredential(realm, user, credentialModel)
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()
。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 Operator 中已弃用的 podDisruptionBudget
在此版本中,我们已弃用 旧式 Keycloak Operator 的 Keycloak CR 中的 podDisruptionBudget
字段。当 Operator 部署在 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 文档。
迁移到 18.0.0
逐步验证
逐步验证是一项新功能。此功能提供 acr
客户端作用域,其中包含一个协议映射器,该映射器应将 acr
声明添加到令牌中。acr
声明现在不会像此版本之前那样自动添加,而是通过使用此客户端作用域和协议映射器来添加。
客户端作用域作为 realm “默认”客户端作用域添加,因此将添加到所有新创建的客户端。出于性能原因,客户端作用域不会在迁移期间自动添加到所有现有客户端。迁移后,客户端默认情况下不会具有 acr
声明。考虑以下可能的措施
-
如果您不打算使用逐步验证功能,但您依赖令牌中的
acr
声明,则可以禁用step_up_authentication
功能。在正常身份验证的情况下,声明将添加值为1
,在 SSO 身份验证的情况下,声明将添加值为0
。 -
通过管理 REST API 或管理控制台手动将
acr
客户端作用域添加到您的客户端。如果您想使用逐步验证,则尤其需要这样做。如果您的 realm 中有大量客户端并且想要对所有客户端使用acr
声明,则可以针对您的数据库触发一些类似于以下的 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-Initiated Logout 规范的注销。不再支持参数 redirect_uri
;此外,在新版本中,用户需要确认注销。当您包含参数 post_logout_redirect_uri
以及带有用于登录的 ID 令牌的参数 id_token_hint
时,可以省略确认并执行自动重定向到应用程序。
现有部署会受到以下影响
-
如果您的应用程序直接使用带有
redirect_uri
参数的注销端点链接,则您可能需要按上述方式更改此链接。考虑完全删除redirect_uri
参数,或将其替换为id_token_hint
和post_logout_redirect_uri
参数。 -
如果您使用 java 适配器并且您的应用程序通过调用
httpServletRequest.logout()
执行注销,则您不会受到影响,因为此调用使用注销端点的后通道变体,并且该变体未更改。 -
如果您使用最新的 javascript 适配器,您也不会受到影响。但是,如果您的应用程序使用旧版本的 JavaScript 适配器,则您会受到影响,因为此适配器使用带有已弃用的
redirect_uri
参数的注销端点变体。在这种情况下,您可能需要升级到最新版本的 JavaScript 适配器。 -
对于 Node.js 适配器,与 JavaScript 适配器适用相同的准则。建议您更新到最新版本,因为旧版本的适配器使用已弃用的
redirect_uri
参数。使用最新的 Node.js 适配器,只要您按照文档或 Node.js 适配器示例中所述使用基于/logout
URL 的注销,您就不会受到影响。但是,如果您的应用程序直接使用方法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
部署脚本时,服务器将自动创建其相应的提供程序,以便您可以在配置身份验证流程、映射器和授权策略时选择它们。
一般来说,更新 realm 的步骤如下
-
升级前,删除您正在使用的任何脚本提供程序。
-
升级后,按照 文档 中的说明部署您的脚本。
-
更新您的身份验证流程、映射器和客户端授权设置,以使用从部署到服务器的脚本创建的提供程序。
帐户控制台 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 来解决。
资源
-
[Patternfly 文档](https://www.patternfly.org)
已知具有重大更改的组件
-
Alert (警报)
-
action
prop 更改为actionClose
-
Expandable (可展开)
-
重命名为
ExpandableSection
-
Title (标题)
-
size 属性现在使用
TitleSizes
-
DataListContent (数据列表内容)
-
noPadding
更改为hasNoPadding
-
Grid, Stack, Level, Gallery (网格、堆叠、层级、画廊)
-
gutter
属性更改为hasGutter
-
Modal (模态框)
-
尺寸控制从例如
isLarge
更改为使用ModalVariant
,例如variant={ModalVariant.large}
-
Select (选择框)
-
ariaLabelTypeAhead
更改为typeAheadAriaLabel
-
isExpanded
更改为isOpen
-
ariaLabelledBy
更改为aria-labelledby
-
DataListContent (数据列表内容)
-
noPadding
更改为hasNoPadding
迁移到 17.0.0
默认分发版现在由 Quarkus 提供支持
Keycloak 的默认分发版现在由 Quarkus 提供支持,这为您配置 Keycloak 和部署自定义提供程序带来了一些重大更改。有关更多信息,请查看 Quarkus 迁移指南。
Keycloak 的 WildFly 分发版现已弃用,支持将于 2022 年 6 月结束。我们建议尽快迁移到 Quarkus 分发版。但是,如果您需要在旧版 WildFly 分发版上保留一段时间,则需要考虑一些更改
-
旧版分发版标签的容器镜像已更改。要使用旧版分发版,请使用标签
legacy
或17.0.0-legacy
。 -
网站上旧版分发版的下载已更改为
keycloak-legacy-17.0.0.[zip|tar.gz]
。
如果您在迁移到 Quarkus 分发版时遇到问题,缺少配置某些内容的能力,或者有一般想法和反馈,请在 GitHub Discussions 中发起讨论。
从预览版 Quarkus 分发版迁移
自 Keycloak 15.1.0 中发布预览版 Quarkus 分发版以来,许多内容已更改。了解已更改内容的理想方法是查看新的 服务器指南。总而言之,更改包括
-
容器现在发布到
quay.io/keycloak/keycloak:latest
和quay.io/keycloak/keycloak:17.0.0
-
网站上的下载重命名为
keycloak-17.0.0.[zip|tar.gz]
。 -
conf/keycloak.properties
更改为conf/keycloak.conf
,这统一了配置文件和 CLI 参数之间的配置键。 -
build options
和runtime configuration
之间更清晰的分离。 -
自定义 Quarkus 配置通过
conf/quarkus.properties
完成。 -
h2-mem
和h2-file
数据库重命名为dev-mem
和dev-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 16 中提供的默认配置文件开始,并应用相关的更改,而不是复制以前版本的 Keycloak 的配置文件。
Keycloak 子系统的配置可以直接复制。
有关 Elytron 子系统的更多信息,请参阅 WildFly 文档。
对于由此带来的不便,我们深感抱歉,并理解这将使所有人升级到 Keycloak 16 变得更加困难,但我们实在找不到替代方法。
值得指出的一件事是切换到 Quarkus 分发版,我们计划在 Keycloak 17 中使其完全受支持,这将使配置和升级 Keycloak 变得更加容易。
有关 WildFly 25 的更多信息,请参阅 WildFly 25 发行说明。
代理环境变量
Keycloak 现在尊重标准 HTTP_PROXY
、HTTPS_PROXY
和 NO_PROXY
环境变量,用于传出的 HTTP 请求。如果您定义了 HTTP_PROXY
变量,但在 SPI 配置中没有指定显式代理映射,则此更改可能会导致意外使用代理服务器。要防止 Keycloak 使用这些环境变量,您可以为所有请求显式创建无代理路由,如 .*;NO_PROXY
。
迁移到 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).xml
和domain.xml
文件中存在一些配置更改。您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。但是,以下是最重要的更改,如果您进行了自己的配置更改,您可能需要注意这些更改-
Infinispan 缓存容器的
module
属性现在已弃用(未使用),并且已替换为modules
属性,该属性表示与此缓存容器的配置关联的模块集。此外,由于使用了 Wildfly 23 作为底层容器,因此各种元素的属性也进行了一些其他更改。例如,managed-executor-service
和managed-scheduled-executor-service
元素现在可以识别新的hung-task-termination-period
属性。有关详细信息,请参阅 Wildfly 23 完整模型参考。
-
升级到 Wildfly 22
Keycloak 服务器已升级为使用 Wildfly 22 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改
- 依赖项更新
-
依赖项已更新为 Wildfly 22 服务器使用的版本。例如,Infinispan 现在是
11.0.8.Final
。 - 配置更改
-
standalone(-ha).xml
和domain.xml
文件中存在一些配置更改。您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。但是,以下是最重要的更改,如果您进行了自己的配置更改,您可能需要注意这些更改-
Eclipse MicroProfile Config、Eclipse MicroProfile Health 和 Eclipse MicroProfile Metrics 子系统已替换为 WildFly 健康子系统 和 WildFly 基础指标子系统。
-
默认的 Wildfly 配置现在可以使用 Elytron 自动生成的自签名证书。有关详细信息,请参阅 专门的
applicationSSC
服务器 SSL 上下文部分。
-
迁移到 12.0.2
只读属性
添加了对只读用户属性的支持。这包括用户属性,这些属性不应由用户或管理员在通过 REST API 或 Keycloak 用户界面更新用户时进行编辑。如果您使用以下功能,这一点尤其重要
-
自定义用户存储提供程序
-
自定义身份验证器
-
自定义 JavaScript 授权策略,这些策略基于某些用户属性建立授权
-
带有用于将 X.509 证书映射到用户身份的自定义属性的 X.509 身份验证器
-
任何其他自定义功能,其中某些用户属性用作存储身份验证/授权/身份上下文的元数据,而不是简单的用户个人资料信息。
有关详细信息,请参阅 威胁模型缓解章节。
迁移到 13.0.0
升级到 Wildfly 22
Keycloak 服务器已升级为使用 Wildfly 22 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但有一些与迁移相关的更改值得一提。
- 依赖项更新
-
依赖项已更新为 Wildfly 22 服务器使用的版本。例如,Infinispan 现在是
11.0.8.Final
。 - 配置更改
-
standalone(-ha).xml
和domain.xml
文件中存在一些配置更改。您应该按照下载 Keycloak 服务器部分自动处理配置文件的迁移。如果需要更多详细信息,例如,因为您自己进行了一些配置更改,则最重要的更改列表如下-
Eclipse MicroProfile Config、Eclipse MicroProfile Health 和 Eclipse MicroProfile Metrics 子系统已替换为 WildFly 健康检查子系统 和 WildFly 基础指标子系统。
-
默认的 Wildfly 配置现在利用了使用 Elytron 自动生成的自签名证书的功能。有关详细信息,请参阅专用的
applicationSSC
服务器 SSL 上下文部分。
-
迁移到 12.0.0
升级到 Wildfly 21
Keycloak 服务器已升级为使用 Wildfly 21 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改
- 依赖项更新
-
依赖项已更新为 Wildfly 21 服务器使用的版本。例如,Infinispan 现在是 11.0.4.Final。
- 配置更改
-
standalone(-ha).xml
和domain.xml
文件中存在一些配置更改。您应该按照 下载 Keycloak 服务器 部分自动处理配置文件的迁移。但是,以下是最重要的更改,如果您进行了自己的配置更改,您可能需要注意这些更改-
Infinispan 缓存的
object-memory
元素现在已弃用(未使用),并替换为heap-memory
元素。
-
跳过为 Docker 协议身份验证创建用户会话
使用 Docker 协议成功进行身份验证后,不会创建用户会话。有关详细信息,请参阅服务器管理指南。
升级到 PatternFly 4
Keycloak 登录主题组件已升级到 PatternFly 4。旧的 PatternFly 3 与新的 PatternFly 4 同时运行,因此可以保留 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).xml
和domain.xml
文件中存在一些配置更改。您应该按照下载 Keycloak 服务器部分自动处理配置文件的迁移。 - 跨数据中心复制更改
-
-
您将需要将 Infinispan 服务器升级到 9.4.19 版本。旧版本可能仍然有效,但由于不再进行测试,因此无法保证。
-
建议在配置 Infinispan 缓存时,使用添加到
remote-store
元素的protocolVersion
属性。当连接到 Infinispan 服务器 9.4.18 时,由于 Keycloak 服务器和 Infinispan 服务器之间的 Infinispan 库版本不同,建议的热棒协议版本为 2.9。有关更多详细信息,请参阅跨数据中心文档。 -
建议在
connectionsInfinispan
子系统下使用remoteStoreSecurityEnabled
属性。有关更多详细信息,请参阅跨数据中心文档。
-
LDAP 无导入错误修复
在之前的 Keycloak 版本中,当 LDAP 提供程序配置为 导入用户
关闭时,即使某些非 LDAP 映射的属性被更改,也可以更新用户。这种情况导致了令人困惑的行为,即属性似乎已更新,但实际上并未更新。在当前版本中,如果任何非 LDAP 映射的属性被更改,则完全不允许执行更新。
这应该不会影响大多数部署,但某些情况下可能会在一些罕见的情况下受到影响。例如,如果您之前尝试使用管理 REST API 更新用户,并且该用户有一些不正确的属性更改,则可以进行更新。在当前版本中,更新是不可能的,您将立即被告知原因。
UserModel 更改
UserModel
中的字段 username
、email
、firstName
和 lastName
已迁移到自定义属性,为在即将到来的版本中向 Keycloak 添加更复杂的用户配置文件做准备。如果数据库包含具有完全相同名称的自定义属性的用户,则需要在升级之前迁移自定义属性。此迁移不会自动发生。否则,它们将不再从数据库中读取,并可能被删除。这种情况意味着现在也可以通过 UserModel.getFirstAttribute(UserModel.USERNAME)
访问和设置 username
。其他字段也存在类似的含义。直接或间接子类化 UserModel
的 SPI 的实现者应确保 setUsername
和 setSingleAttribute(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_endpoint
和 introspection_endpoint
。后者是 RFC-8414 定义的端点。前者以前已弃用,现在已删除。
迁移到 9.0.1
JavaScript 适配器中的旧版 Promise
不再需要在 JavaScript 适配器中设置 promiseType,并且两者都同时可用。建议尽快更新应用程序以使用原生 Promise API (then
和 catch
),因为旧版 API (success
和 error
) 将在某个时候被删除。
重复的顶级组
9.0.1 版本修复了一个问题,该问题可能会在领域中创建重复的顶级组。然而,之前重复组的存在使升级过程失败。如果 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;
在每个领域中,只能存在一个同名的顶级组。重复项应在升级前进行审核和删除。升级中的错误包含消息 Change Set META-INF/jpa-changelog-9.0.1.xml::9.0.1- KEYCLOAK-12579-add-not-null-constraint::keycloak failed.
迁移到 8.0.2
更多身份验证流程更改
- 同一流程中不支持 REQUIRED 和 ALTERNATIVE 执行
-
在以前的版本中,可以在同一身份验证流程中的同一级别拥有 REQUIRED 和 ALTERNATIVE 执行。这种方法存在一些问题,我们在身份验证 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).xml
和domain.xml
文件中存在一些配置更改。您应该按照下载 Keycloak 服务器部分自动处理配置文件的迁移。 - 跨数据中心复制更改
-
-
您将需要将 Infinispan 服务器升级到 9.4.19 版本。旧版本可能仍然有效,但由于我们不再进行测试,因此无法保证。
-
将脚本部署到服务器
到目前为止,管理员可以通过 Keycloak 管理控制台以及 RESTful 管理 API 将脚本上传到服务器。
从现在开始,默认情况下此功能已禁用,用户应首选将脚本直接部署到服务器。有关更多详细信息,请查看JavaScript 提供程序。
身份验证流程更改
我们对身份验证流程进行了一些重构和改进,这需要在迁移期间引起一些注意。
- 已删除 OPTIONAL 执行要求
-
关于迁移,最重要的更改是从身份验证执行中删除对 OPTIONAL 要求的支持,并将其替换为 CONDITIONAL 要求,这允许更大的灵活性。以前版本中配置的现有 OPTIONAL 身份验证器将替换为 CONDITIONAL 子流程。这些子流程将
条件 - 用户已配置
条件配置为第一个执行,并将以前的 OPTIONAL 身份验证器(例如OTP 表单
)配置为第二个执行。从用户的角度来看,身份验证期间的行为与以前版本相同。 - Java SPI 中的更改
-
Java 身份验证 SPI 和凭据提供程序 SPI 中存在一些更改。
Authenticator
接口未更改,但如果您正在开发更高级的身份验证器,这些身份验证器引入了一些新的凭据类型(CredentialModel
的子类),则可能会受到影响。CredentialProvider
接口发生了一些更改,并引入了一些新接口,例如CredentialValidator
。此外,如果您的身份验证器支持 OPTIONAL 执行要求,则您可能会受到影响。建议仔细检查服务器开发指南中的最新身份验证示例,以获取更多详细信息。 - Freemarker 模板更改
-
Freemarker 模板中存在一些更改。如果您有自己的主题,其中包含用于登录表单或某些帐户表单的自定义 Freemarker 模板,特别是与 OTP 相关的表单,则可能会受到影响。建议仔细检查最新 Keycloak 中的 Freemarker 模板中的更改,并根据其调整您的模板。
迁移到 7.0.0
升级到 Wildfly 17
Keycloak 服务器已升级为使用 Wildfly 17 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改
- 依赖项更新
-
依赖项已更新为 Wildfly 17 服务器使用的版本。例如,Infinispan 现在是 9.4.14.Final。
- 配置更改
-
standalone(-ha).xml
和domain.xml
文件中存在一些配置更改。您应该按照下载 Keycloak 服务器部分自动处理配置文件的迁移。 - 跨数据中心复制更改
-
-
您将需要将 Infinispan 服务器升级到 9.4.19 版本。旧版本可能仍然有效,但由于我们不再进行测试,因此无法保证。
-
迁移到 6.0.0
升级到 Wildfly 16
Keycloak 服务器已升级为使用 Wildfly 16 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改
- 依赖项更新
-
依赖项已更新为 Wildfly 16 服务器使用的版本。例如,Infinispan 现在是 9.4.8.Final。
- 配置更改
-
standalone(-ha).xml
和domain.xml
文件中存在一些配置更改。您应该按照下载 Keycloak 服务器部分自动处理配置文件的迁移。 - 跨数据中心复制更改
-
-
您将需要将 Infinispan 服务器升级到 9.4.19 版本。旧版本可能仍然有效,但由于我们不再进行测试,因此无法保证。
-
新的可选客户端作用域
我们添加了一个新的 microprofile-jwt
可选客户端作用域来处理 MicroProfile/JWT Auth 规范中定义的声明。这个新的客户端作用域定义了协议映射器,用于将已验证用户的用户名设置为 upn
声明,并将领域角色设置为 groups
声明。
能够将 prompt=none 传播到默认 IDP
我们在 OIDC 身份提供程序配置中添加了一个名为 接受来自客户端的 prompt=none 转发
的新开关,以标识能够处理包含 prompt=none
查询参数的转发请求的 IDP。
到目前为止,当收到带有 prompt=none
的身份验证请求时,如果用户未在领域中进行身份验证,则领域将返回 login_required
错误,而无需检查用户是否已通过 IDP 进行身份验证。从现在开始,如果可以为身份验证请求确定默认 IDP(通过使用 kc_idp_hint
查询参数或为领域设置默认 IDP),并且如果为 IDP 启用了 接受来自客户端的 prompt=none 转发
开关,则身份验证请求将转发到 IDP 以检查用户是否已在那里进行身份验证。
重要的是要注意,仅当指定了默认 IDP 时,此开关才会被考虑在内,在这种情况下,我们知道将身份验证请求转发到哪里,而无需提示用户选择 IDP。如果无法确定默认 IDP,我们无法假定将使用哪个 IDP 来满足身份验证请求,因此不会执行请求转发。
迁移到 5.0.0
升级到 Wildfly 15
Keycloak 服务器已升级为使用 Wildfly 15 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改
- 依赖项更新
-
依赖项已更新为 Wildfly 15 服务器使用的版本。例如,Infinispan 现在是 9.4.3.Final。
- 配置更改
-
standalone(-ha).xml
和domain.xml
文件中存在一些配置更改。您应该按照下载 Keycloak 服务器部分自动处理配置文件的迁移。 - 跨数据中心复制更改
-
-
您将需要将 Infinispan 服务器升级到 9.4.19 版本。旧版本可能仍然有效,但由于我们不再进行测试,因此无法保证。
-
迁移到 4.8.2
Google 身份提供程序已更新为使用 Google Sign-in 身份验证系统
Keycloak 4.8.1 及更早版本中的 Google 身份提供程序实现依赖于 Google+ API 端点进行授权和获取用户个人资料。从 2019 年 3 月起,Google 将取消对 Google+ API 的支持,转而使用新的 Google Sign-in 身份验证系统。Keycloak 身份提供程序已更新为使用新的端点,因此如果正在使用此集成,请确保升级到 Keycloak 4.8.2 或更高版本。
如果您遇到错误,提示在目录中找不到应用程序标识符,您将需要在 Google API 控制台 门户中重新注册客户端应用程序,以获取新的应用程序 ID 和密钥。
您可能需要调整自定义映射器,以适应 Google+ 用户信息端点提供的非标准声明,以及 Google Sign-in API 以不同名称提供的声明。请查阅 Google 文档,以获取有关可用声明的最新信息。
LinkedIn 社交代理已更新为 LinkedIn API 的版本 2
根据 LinkedIn 的说法,所有开发人员都需要迁移到其 API 和 OAuth 2.0 的版本 2.0。因此,我们更新了 LinkedIn 社交代理。
使用此代理的现有部署在尝试使用 LinkedIn API 的版本 2 获取用户个人资料时,可能会开始遇到错误。此错误可能与用于配置代理的客户端应用程序缺乏授权访问 Profile API 或在身份验证过程中请求特定 OAuth2 作用域的权限有关。
即使对于新创建的 LinkedIn 客户端应用程序,您也需要确保客户端能够请求 r_liteprofile
和 r_emailaddress
OAuth2 作用域(至少),以及客户端应用程序可以从 https://api.linkedin.com/v2/me
端点获取当前成员的个人资料。
由于 LinkedIn 在访问成员信息方面施加的这些隐私限制,以及当前成员的 Profile API 返回的声明集有限,LinkedIn 社交代理现在使用成员的电子邮件地址作为默认用户名。这意味着在身份验证期间发送授权请求时,始终会设置 r_emailaddress
。
迁移到 4.6.0
新的默认客户端作用域
我们添加了新的领域默认客户端作用域 roles
和 web-origins
。这些客户端作用域包含协议映射器,用于将用户的角色和允许的 Web 源添加到令牌。在迁移期间,这些客户端作用域应自动添加到所有 OpenID Connect 客户端作为默认客户端作用域。因此,数据库迁移完成后无需进行任何设置。
协议映射器 SPI 添加
与此相关的是,对(不受支持的)协议映射器 SPI 进行了少量添加。只有当您实现了自定义 ProtocolMapper 时,才可能会受到影响。ProtocolMapper 接口上引入了一个新的 getPriority()
方法。该方法已设置为返回 0 的默认实现。如果您的协议映射器实现依赖于访问令牌 realmAccess
或 resourceAccess
属性中的角色,则可能需要提高映射器的优先级。
受众解析
现在,对于已验证用户在令牌中至少有一个客户端角色的所有客户端,其受众会自动添加到访问令牌中的 aud
声明中。另一方面,访问令牌可能不会自动包含为其颁发令牌的前端客户端的受众。有关更多详细信息,请阅读服务器管理指南。
JavaScript 适配器 Promise
要将原生 JavaScript Promise 与 JavaScript 适配器一起使用,现在需要在 init 选项中将 promiseType
设置为 native
。
过去,如果原生 Promise 可用,则会返回一个包装器,该包装器同时提供旧版 Keycloak Promise 和原生 Promise。这导致了一些问题,因为错误处理程序并非总是在原生错误事件之前设置,从而导致 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 或更高版本。
由于应用程序的 ID 格式发生更改,在“Live SDK 应用程序”下注册的旧版客户端应用程序将无法与 Microsoft Graph 端点一起使用。如果您遇到错误,提示在目录中找不到应用程序标识符,您将需要在 Microsoft 应用程序注册 门户中重新注册客户端应用程序,以获取新的应用程序 ID。
升级到 Wildfly 14
Keycloak 服务器已升级为使用 Wildfly 14 作为底层容器。这不直接涉及任何特定的 Keycloak 服务器功能,但是,请注意与迁移相关的这些更改
- 依赖项更新
-
依赖项已更新为 Wildfly 14 服务器使用的版本。例如,Infinispan 现在是 9.3.1.Final。
- 配置更改
-
standalone(-ha).xml
和domain.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).xml
和domain.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.0.0
客户端模板已更改为客户端作用域
我们增加了对客户端作用域的支持,这在迁移期间需要一些注意。
- 客户端模板已更改为客户端 Scope
-
客户端模板已更改为客户端作用域。如果您有任何客户端模板,它们的协议映射器和角色作用域映射将被保留。
- 名称中替换了空格
-
名称中带有空格字符的客户端模板已通过将空格替换为下划线来重命名,因为客户端作用域的名称中不允许空格。例如,客户端模板
my template
将更改为客户端作用域my_template
。 - 将客户端作用域链接到客户端
-
对于具有客户端模板的客户端,相应的客户端作用域现在作为
Default Client Scope
添加到客户端。因此,协议映射器和角色作用域映射将在客户端上保留。 - 领域默认客户端作用域未与现有客户端链接
-
在迁移期间,内置客户端作用域列表以及
Realm Default Client Scopes
列表被添加到每个领域。但是,现有客户端不会升级,新的客户端作用域不会自动添加到它们。此外,所有协议映射器和角色作用域映射都保留在现有客户端上。在新版本中,当您创建一个新客户端时,它会自动附加领域默认客户端作用域,并且没有任何协议映射器附加到它。我们在迁移期间没有更改现有客户端,因为无法正确检测自定义项,例如,您将为客户端的协议映射器进行自定义。如果您想更新现有客户端(从它们中删除协议映射器并将它们与客户端作用域链接),您需要手动执行此操作。 - 需要再次确认授权同意
-
客户端作用域的更改需要重构授权同意。授权同意现在指向客户端作用域,而不是角色或协议映射器。由于此更改,用户先前确认的持久授权同意不再有效,用户需要在迁移后再次确认授权同意页面。
- 删除了一些配置开关
-
从角色详情中删除了开关
Scope Param Required
。从协议映射器详情中删除了开关Consent Required
和Consent Text
。这些开关已由客户端作用域功能取代。
授权服务的更改
我们增加了对 UMA 2.0 的支持。这个版本的 UMA 规范对如何从服务器获取权限引入了一些重要的更改。
以下是 UMA 2.0 支持引入的主要更改。有关详细信息,请参阅 授权服务指南。
- 授权 API 已删除
-
在 UMA 2.0(UMA 1.0)之前,客户端应用程序使用授权 API 以 RPT 格式从服务器获取权限。新版本的 UMA 规范已删除了授权 API,Keycloak 也已将其删除。在 UMA 2.0 中,现在可以通过使用特定的授权类型从令牌端点获取 RPT。有关详细信息,请参阅 授权服务指南。
- Entitlement API 已删除
-
随着 UMA 2.0 的引入,我们决定利用令牌端点和 UMA 授权类型,以允许从 Keycloak 获取 RPT,并避免使用不同的 API。Entitlement API 提供的功能保持不变,并且仍然可以为一组或多个资源和作用域获取权限,或者在未提供资源或作用域的情况下从服务器获取所有权限。有关详细信息,请参阅 授权服务指南。
- UMA Discovery 端点的更改
-
UMA Discovery 文档已更改,请参阅 授权服务指南 了解详细信息。
- Keycloak 授权 JavaScript 适配器的更改
-
Keycloak 授权 JavaScript 适配器 (keycloak-authz.js) 已更改,以符合 UMA 2.0 引入的更改,同时保持与以前相同的行为。主要的更改是如何调用
authorization
和entitlement
方法,现在它们期望一个特定的对象类型来表示授权请求。这个新的对象类型通过支持 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 中使用 scope=openid
到 Keycloak。现在我们也更改了服务器部分,只有当真正使用 scope=openid
时,ID 令牌才会发送到应用程序。如果未使用,则将跳过 ID 令牌,并且只会将访问令牌和刷新令牌发送到应用程序。这也允许您有目的地省略 ID 令牌的生成 - 例如,为了空间或性能目的。
直接授权(OAuth2 资源所有者密码凭据授权)和服务帐户登录(OAuth2 客户端凭据授权)现在默认情况下也不使用 ID 令牌。您需要显式添加 scope=openid
参数才能包含 ID 令牌。
身份验证会话和操作令牌
我们正在努力支持多数据中心。作为初始步骤,我们引入了身份验证会话和操作令牌。身份验证会话取代了先前版本中使用的客户端会话。操作令牌目前特别用于身份验证器或 requiredActionProvider 需要向用户发送电子邮件并要求用户单击电子邮件中的链接的场景。
以下是与此相关的具体更改,可能会影响您的迁移。
与此相关的第一个更改是在 standalone.xml
或 standalone-ha.xml
中引入新的 Infinispan 缓存 authenticationSessions
和 actionTokens
。如果您使用我们的迁移 CLI,则无需过多担心,因为您的 standalone(-ha).xml
文件将自动迁移。
第二个更改是更改了身份验证 SPI 中某些方法的签名。如果您使用自定义 Authenticator
或 RequiredActionProvider
,这可能会影响您。类 AuthenticationFlowContext
和 RequiredActionContext
现在允许检索身份验证会话而不是客户端会话。
我们还添加了一些对粘性会话的初始支持。如果您不想受其影响并希望获得更好的性能,您可能需要更改您的负载均衡器/代理服务器并对其进行配置。路由被添加到新的 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.4.0
服务器 SPI 分割为服务器 SPI 和服务器 SPI Private
keycloak-server-spi 模块已拆分为 keycloak-server-spi 和 keycloak-server-spi-private。keycloak-server-spi 中的 API 在次要版本之间不会更改,而我们保留在次要版本之间更改 keycloak-server-spi-private 中 API 的权利,并且很可能会更改。
迁移到 2.3.0
不推荐使用 realm-public-key
适配器属性
在 2.3.0 版本中,我们添加了对公钥轮换的支持。当管理员在 Keycloak 管理控制台中轮换领域密钥时,客户端适配器将能够识别它并自动从 Keycloak 下载新的公钥。但是,只有当您的适配器中没有带有硬编码公钥的 realm-public-key
选项时,才会进行新的密钥的自动下载。因此,我们不再建议在适配器配置中使用 realm-public-key
选项。
请注意,此选项仍然受支持,但只有当您真的想在适配器配置中拥有硬编码的公钥并且永远不从 Keycloak 下载公钥时,它才可能有用。理论上,这样做的一个原因可能是为了避免中间人攻击,如果您在适配器和 Keycloak 之间有不受信任的网络,但在这种情况下,更好的选择是使用 HTTPS,这将保护适配器和 Keycloak 之间的所有请求。
迁移到 2.2.0
databaseSchema
属性 已弃用
JPA 和 Mongo 的 databaseSchema
属性现在都 已弃用 并且 被 initializeEmpty
和 migrationStrategy
替换。initializeEmpty
可以设置为 true
或 false
,并控制是否应初始化空数据库。migrationStrategy
可以设置为 update
、validate
和 manual
。manual
仅支持关系数据库,并将创建一个 SQL 文件,其中包含对数据库架构的必要更改。请注意,对于 Oracle 数据库,创建的 SQL 文件包含 Oracle SQL 客户端理解的 SET DEFINE OFF
命令。如果该脚本要被任何其他客户端使用,请将这些行替换为您选择的工具的等效命令,该命令禁用变量扩展,或者如果此类功能不适用,则完全删除它。
迁移到 1.9.0
主题和提供程序目录已移动
我们已将主题和提供程序目录从 standalone/configuration/themes
和 standalone/configuration/providers
移动到 themes
和 providers
。如果您添加了自定义主题和提供程序,则需要将它们移动到新位置。您还需要更新 keycloak-server.json
,因为它已因此而更改。
仅当 Keycloak 开启时,适配器子系统才引入依赖项
以前,如果您已将我们的 SAML 或 OIDC Keycloak 子系统适配器安装到 WildFly 或 JBoss EAP 中,我们将自动将 Keycloak 客户端 jar 包含到每个应用程序中,无论您是否正在使用 Keycloak。现在,只有当您为该适配器开启 Keycloak 身份验证(通过子系统或 web.xml 中的 auth-method)时,这些库才会被添加到您的部署中。
身份验证响应中的会话状态参数已重命名
在 OpenID Connect 身份验证响应中,我们曾经将会话状态作为 session-state
返回,这根据规范是不正确的,并且已重命名为 session_state
。
已弃用的 OpenID Connect 端点
在 1.2 中,我们弃用了一些与 OpenID Connect 规范不一致的端点,这些端点现在已被删除。这也适用于验证令牌端点,该端点已在 1.8 中被新的内省端点取代。
模块和源代码重组
我们的大部分模块和源代码已合并到两个 Maven 模块中:keycloak-server-spi 和 keycloak-services。SPI 接口位于 server-spi 中,实现位于 keycloak-services 中。所有 JPA 依赖模块都已合并到 keycloak-model-jpa 下。Mongo 和 Infinispan 也同样如此,分别位于模块 keycloak-model-mongo 和 keycloak-model-infinispan 下。
迁移到 1.8.0
OAuth2 令牌内省
为了更符合 OAuth2 规范,我们添加了一个新的令牌内省端点。新端点可以通过 /realms/{realm-name}/protocols/openid-connect/token/introspect
访问,并且完全基于 RFC-7662
。
/realms/{realm-name}/protocols/openid-connect/validate
端点现在已弃用,我们强烈建议您尽快迁移到新的内省端点。此更改的原因是 RFC-7662 提供了更标准和安全的内省端点。
新的令牌内省 URL 现在可以从 OpenID Connect 提供商的配置中获取,地址为 /realms/{realm-name}/.well-known/openid-configuration
。您将在响应中找到一个名为 token_introspection_endpoint
的声明。只有 confidential clients
允许调用新端点,这些客户端通常充当资源服务器,并查找令牌元数据以执行本地授权检查。
迁移到 1.7.0.CR1
默认情况下,客户端禁用直接访问授权
为了更符合 OpenID Connect 规范,我们在管理控制台中添加到客户端设置页面添加了标志,您可以在其中启用/禁用各种 OpenID Connect/OAuth2 流(标准流、隐式流、直接访问授权、服务帐户)。作为其中的一部分,对于新客户端,我们默认禁用 Direct Access Grants
(对应于 OAuth2 Resource Owner Password Credentials Grant
)。
从以前版本迁移的客户端,只有在其具有 Direct Grants Only
标志的情况下才启用 Direct Access Grants
。Direct Grants Only
标志已删除,因为如果您启用直接访问授权并禁用标准+隐式流,您将获得相同的效果。
我们还为每个领域添加了内置客户端 admin-cli
。此客户端启用了 Direct Access Grants
。因此,如果您正在使用管理 REST API 或 Keycloak admin-client,您应该更新您的配置以使用 admin-cli
而不是 security-admin-console
,因为后者默认情况下不再启用直接访问授权。
“首次登录时更新个人资料”选项已从身份提供商移动到审核个人资料身份验证器
在此版本中,我们添加了 First Broker Login
,它允许您指定当新用户通过身份提供商(或社交提供商)登录,但尚不存在链接到社交帐户的 Keycloak 用户时,应执行的确切操作。作为此工作的一部分,我们向身份提供商添加了选项 First Login Flow
,您可以在其中指定流程,然后在管理控制台的“Authentication
”选项卡下配置此流程。
我们还从身份提供商设置中删除了选项 Update Profile On First Login
,并将其移动到 Review Profile
身份验证器的配置中。因此,一旦您指定了应为您的身份提供商使用哪个流程(默认为 First Broker Login
流程),您就可以转到“Authentication
”选项卡,选择流程,然后在 Review Profile
身份验证器下配置该选项。
不再支持 web.xml 中的元素 'form-error-page'
web.xml 中的 form-error-page 将不再适用于客户端适配器身份验证错误。您必须为各种 HTTP 错误代码定义 error-page。如果您想捕获和处理适配器错误情况,请参阅文档以获取更多详细信息。
IdentityProviderMapper 更改
接口本身和方法签名没有更改。但是,行为上存在一些更改。我们在此版本中添加了 First Broker Login
流,并且方法 IdentityProviderMapper.importNewUser
现在在 First Broker Login
流完成后调用。因此,如果您想在 Review Profile
页面中提供任何属性,您需要使用方法 preprocessFederatedIdentity
而不是 importNewUser
。您可以通过调用 BrokeredIdentityContext.setUserAttribute
来设置任何属性,这将可在 Review profile
页面上使用。
迁移到 1.6.0.Final
刷新令牌不再可重用的选项
旧版本的 Keycloak 允许多次重用刷新令牌。Keycloak 仍然允许这样做,但也提供了一个选项 Revoke refresh token
来禁止它。该选项位于管理控制台的令牌设置下。当使用刷新令牌获取新的访问令牌时,也会包含一个新的刷新令牌。启用该选项后,下次刷新访问令牌时应使用此新刷新令牌。将不可能多次重用旧的刷新令牌。
迁移到 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
Direct Grant API 始终启用
过去,Direct Grant API(或资源所有者密码凭据)默认情况下是禁用的,并且存在在 realm 上启用它的选项。现在 Direct Grant API 始终启用,并且移除了 realm 的启用/禁用选项。
UserFederationProvider 已更改
UserFederationProvider 接口中存在一些小的更改。当升级到较新版本并升级一些签名已更改的方法时,您可能需要同步您的实现。更改非常小,但为了提高联合的性能是必要的。
WildFly 9.0.0.Final
继上次发布中所做的分发更改之后,Keycloak 的独立下载现在基于 WildFly 9.0.0.Final。这也影响了 overlay,它只能部署到 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
从 1.1.0.Final 迁移到 1.2.0.Beta1
访问令牌和 ID 令牌中的 iss
访问令牌和 ID 令牌中 iss
声明的值已从 realm name
更改为 realm url
。这是 OpenID Connect 规范要求的。如果您正在使用我们的适配器,则无需更改,除非您一直在使用 bearer-only 并且未指定 auth-server-url
,现在您必须添加它。如果您正在使用另一个库(或 RSATokenVerifier),则在验证 iss
时需要进行相应的更改。
OpenID Connect 端点
为了符合 OpenID Connect 规范,身份验证和令牌端点已更改为具有单个身份验证端点和单个令牌端点。按照规范,response_type
和 grant_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 中包含的主题。
声明更改
以前,在管理控制台中,应用程序和 OAuth 客户端存在一个专用的 Claims
选项卡。它用于配置哪些属性应进入特定应用程序/客户端的访问令牌。此选项卡已被删除,并替换为更灵活的协议映射器。
您无需担心从先前版本迁移数据库。我们为 RDBMS 和 Mongo 都编写了迁移脚本,这应确保为特定应用程序/客户端配置的声明将转换为相应的协议映射器(尽管备份数据库后再迁移到较新版本仍然更安全)。这同样适用于从先前版本导出的 JSON 表示形式。
社交迁移到身份代理
我们重构了社交提供商 SPI,并将其替换为更灵活的 Identity Brokering SPI。管理控制台中的 Social
选项卡已重命名为 Identity Provider
选项卡。
同样,您无需担心从先前版本迁移数据库,就像声明/协议映射器一样。社交提供商的配置和用户的“社交链接”都将转换为相应的身份提供商。
您唯一需要做的操作是更改特定第三方社交提供商的管理控制台中允许的 Redirect URI
。您可以先转到 Keycloak 管理控制台,然后从配置身份提供商的页面复制 Redirect URI。然后,您可以简单地将其粘贴为允许的 Redirect URI 到第三方提供商的管理控制台(例如,Facebook 管理控制台)。
从 1.1.0.Beta1 迁移到 1.1.0.Beta2
-
适配器现在是单独下载的。它们不包含在 appliance 和 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 Token 和 OIDC ID Token 规范。'aud' 声明必须是客户端 ID,我们过去在那里存储 realm 名称并对其进行验证。
从 1.0 RC-1 迁移到 RC-2
-
许多 info 级别的日志记录已更改为 debug。此外,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”页面下。现在它位于用户→联合下。“添加提供商”将显示“ldap”选项。
-
身份验证 SPI 已被删除并重写。新的 SPI 是 UserFederationProvider,它更灵活。
-
ssl-not-required
+ssl-required
+all
+external
+none
-
DB Schema 再次更改。
-
现在创建的应用程序默认具有完整的作用域。这意味着如果您不需要,则不必配置应用程序的作用域。
-
用于导入 realm 数据的 JSON 文件格式已更改。现在,角色映射在特定用户的 JSON 记录下可用。
从 1.0 Alpha 4 迁移到 Beta 1
-
DB Schema 已更改。我们已将数据库导出添加到 Beta 1,但没有添加从旧版本导入数据库的功能。这将在未来的版本中支持。
-
对于除 bearer-only 应用程序之外的所有客户端,您必须至少指定一个重定向 URI。除非您为该应用程序指定了有效的重定向 URI,否则 Keycloak 将不允许您登录。
-
Direct Grant 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 中的 Subject 已更改为用户 ID。
从 1.0 Alpha 1 迁移到 Alpha 2
-
DB Schema 已更改。在 Alpha 2 中,我们还没有任何数据迁移实用程序。
-
JBoss 和 WildFly 适配器现在通过 WildFly 子系统安装。请查看适配器安装文档。现在需要编辑 standalone.xml。
-
引入了一种新的凭据类型“secret”。与其他凭据类型不同,它以明文形式存储在数据库中,并且可以在管理控制台中查看。
-
不再需要应用程序和 OAuth 客户端凭据。这些客户端类型现在被硬编码为使用“secret”凭据类型。
-
由于应用程序和 OAuth 客户端的“secret”凭据更改,您必须更新 keycloak.json 配置文件,并在管理控制台中的应用程序或 OAuth 客户端凭据选项卡中重新生成 secret。
升级 Keycloak 服务器
您需要在升级适配器之前升级服务器。
升级准备
在升级服务器之前,请执行以下步骤。
-
关闭 Keycloak。
-
备份旧安装,例如配置、主题等。
-
如果启用了 XA 事务,请处理任何打开的事务并删除
data/transaction-logs/
事务目录。 -
使用关系数据库文档中的说明备份数据库。
升级服务器后,数据库将不再与旧服务器兼容。如果您需要还原升级,请先还原旧安装,然后从备份副本还原数据库。
如果您的当前设置中禁用了 |
有关暴力破解检测和当前正在进行的身份验证流程的失败登录信息仅存储在内部缓存中,这些缓存在 Keycloak 关闭时会被清除。当前正在进行身份验证、更改密码或重置密码的用户需要在 Keycloak 启动并再次运行后重新启动身份验证流程。 |
下载 Keycloak 服务器
准备好升级后,您可以下载服务器。
-
从 Keycloak 网站下载并解压 keycloak-26.2.0.zip。
解压此文件后,您应该有一个名为
keycloak-26.2.0
的目录。 -
将此目录移动到所需位置。
-
将
conf/
、providers/
和themes/
从旧安装复制到新安装。
迁移数据库
Keycloak 可以自动迁移数据库模式,或者您可以选择手动执行。默认情况下,当您首次启动新安装时,数据库会自动迁移。
自动关系数据库迁移
要执行自动迁移,请启动连接到所需数据库的服务器。如果新服务器版本的数据库模式已更改,则迁移会自动开始,除非数据库记录过多。
例如,在具有数百万条记录的表上创建索引可能非常耗时,并可能导致严重的服务中断。因此,自动迁移存在 300000
条记录的阈值。如果记录数超过此阈值,则不会创建索引。相反,您会在服务器日志中找到警告,其中包含您可以手动应用的 SQL 命令。
要更改阈值,请为 connections-liquibase
提供程序设置 index-creation-threshold
属性值
kc.[sh|bat] start --spi-connections-liquibase-quarkus-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>
有关如何将此文件应用于数据库的更多详细信息,请参阅关系数据库的文档。将更改写入文件后,服务器将退出。
迁移主题
如果您创建了自定义主题,则必须将这些主题迁移到新服务器。此外,对内置主题的任何更改可能也需要在您的自定义主题中反映出来,具体取决于您自定义的方面。
-
将您的自定义主题从旧服务器的
themes
目录复制到新服务器的themes
目录。 -
使用以下部分迁移模板、消息和样式。
-
如果您自定义了迁移更改中列出的任何更新的模板,请比较基本主题中的模板,以检查您需要应用的任何更改。
-
如果您自定义了消息,则可能需要更改键或值,或添加其他消息。
-
如果您自定义了任何样式并且您正在扩展 Keycloak 主题,请查看对样式的更改。如果您正在扩展基本主题,则可以跳过此步骤。
-
迁移模板
如果您自定义了任何模板,请查看新版本以决定是否更新您的自定义模板。如果您进行了细微的更改,则可以将更新后的模板与您的自定义模板进行比较。但是,如果您进行了许多更改,请考虑将新模板与您的自定义模板进行比较。此比较将向您显示您需要进行的更改。
您可以使用 diff 工具来比较模板。以下屏幕截图比较了登录主题中的 info.ftl
模板和一个示例自定义主题
此比较表明,第一个更改 (Hello world!!
) 是自定义,而第二个更改 (if pageRedirectUri
) 是对基本主题的更改。通过将第二个更改复制到您的自定义模板,您已成功更新了您的自定义模板。
在另一种方法中,以下屏幕截图比较了旧安装中的 info.ftl
模板与新安装中更新的 info.ftl
模板
此比较显示了基本模板中已更改的内容。然后,您可以手动将相同的更改应用到您的修改后的模板。由于此方法更复杂,因此仅在第一种方法不可行时才使用此方法。
升级 Keycloak 适配器
升级 Keycloak 服务器后,您可以升级适配器。早期版本的适配器可能与更高版本的 Keycloak 服务器一起使用,但早期版本的 Keycloak 服务器可能无法与更高版本的适配器一起使用。
与旧版本适配器的兼容性
较新版本的 Keycloak 服务器可能与旧版本的适配器一起使用。但是,Keycloak 服务器的一些修复程序可能会破坏与旧版本适配器的兼容性。例如,OpenID Connect 规范的新实现可能与旧客户端适配器版本不匹配。
对于这种情况,您可以使用兼容模式。对于 OpenID Connect 客户端,管理控制台在客户端详细信息页面上包含OpenID Connect 兼容模式。使用此选项,您可以禁用 Keycloak 服务器的一些新方面,以保持与旧客户端适配器的兼容性。有关更多详细信息,请参阅各个开关的工具提示。
升级 EAP 适配器
要升级 WildFly 适配器,请完成以下步骤
-
下载新的适配器归档文件。
-
通过删除
WILDFLY_HOME/modules/system/add-ons/keycloak/
目录来删除之前的适配器模块。 -
将下载的归档文件解压缩到
WILDFLY_HOME
。
升级 Node.js
适配器
要升级 Node.js
适配器,请查看 Node.js 适配器
文档