Keycloak 功能和概念
Keycloak 是一个用于 Web 应用程序和 RESTful Web 服务的单点登录解决方案。Keycloak 的目标是简化安全性,以便应用程序开发人员可以轻松地保护他们在组织中部署的应用程序和服务。开发人员通常需要自己编写的安全性功能开箱即用,并且可以轻松地根据您组织的个性化需求进行定制。Keycloak 为登录、注册、管理和帐户管理提供可自定义的用户界面。您还可以使用 Keycloak 作为集成平台,将其连接到现有的 LDAP 和 Active Directory 服务器。您还可以将身份验证委派给 Facebook 和 Google 等第三方身份提供程序。
功能
Keycloak 提供以下功能
-
浏览器应用程序的单点登录和单点注销。
-
OpenID Connect 支持。
-
OAuth 2.0 支持。
-
SAML 支持。
-
身份代理 - 使用外部 OpenID Connect 或 SAML 身份提供程序进行身份验证。
-
社交登录 - 启用使用 Google、GitHub、Facebook、Twitter 和其他社交网络登录。
-
用户联合 - 从 LDAP 和 Active Directory 服务器同步用户。
-
Kerberos 桥接 - 自动验证已登录到 Kerberos 服务器的用户的身份。
-
用于集中管理用户、角色、角色映射、客户端和配置的管理员控制台。
-
允许用户集中管理其帐户的帐户控制台。
-
主题支持 - 自定义所有面向用户的页面,以与您的应用程序和品牌形象相集成。
-
双因素身份验证 - 支持通过 Google Authenticator 或 FreeOTP 进行 TOTP/HOTP 验证。
-
登录流程 - 可选的用户自助注册、密码恢复、电子邮件验证、要求密码更新等。
-
会话管理 - 管理员和用户自己可以查看和管理用户会话。
-
令牌映射器 - 按照您希望的方式将用户属性、角色等映射到令牌和声明中。
-
每个域、应用程序和用户的 Not-before 撤销策略。
-
CORS 支持 - 客户端适配器内置了对 CORS 的支持。
-
服务提供商接口 (SPI) - 许多 SPI 可用于自定义服务器的各个方面。身份验证流程、用户联合提供商、协议映射器等等。
-
支持任何具有 OpenID Connect Relying Party 库或 SAML 2.0 服务提供商库的平台/语言。
Keycloak 基本操作
Keycloak 是一个独立的服务器,您可以在您的网络上管理它。应用程序配置为指向此服务器并由此服务器保护。Keycloak 使用开放协议标准(如 OpenID Connect 或 SAML 2.0)来保护您的应用程序。浏览器应用程序将用户的浏览器从应用程序重定向到 Keycloak 身份验证服务器,用户在其中输入其凭据。此重定向非常重要,因为用户与应用程序完全隔离,并且应用程序永远不会看到用户的凭据。相反,应用程序会获得经过加密签名的身份令牌或断言。这些令牌可以包含身份信息,如用户名、地址、电子邮件和其他个人资料数据。它们还可以包含权限数据,以便应用程序可以做出授权决策。这些令牌还可以用于对基于 REST 的服务进行安全调用。
核心概念和术语
在尝试使用 Keycloak 保护您的 Web 应用程序和 REST 服务之前,请考虑以下核心概念和术语。
- 用户
-
用户是能够登录到您的系统的实体。他们可以拥有与其关联的属性,如电子邮件、用户名、地址、电话号码和生日。他们可以被分配到组成员资格并被分配特定的角色。
- 身份验证
-
识别和验证用户的过程。
- 授权
-
授予用户访问权限的过程。
- 凭据
-
凭据是 Keycloak 用于验证用户身份的数据片段。一些示例包括密码、一次性密码、数字证书,甚至是指纹。
- 角色
-
角色标识用户的类型或类别。
Admin
、user
、manager
和employee
都是组织中可能存在的典型角色。应用程序通常将访问权限和许可权分配给特定角色,而不是单个用户,因为处理用户可能过于细粒度且难以管理。 - 用户角色映射
-
用户角色映射定义角色和用户之间的映射。一个用户可以与零个或多个角色关联。此角色映射信息可以封装到令牌和断言中,以便应用程序可以决定对其管理的各种资源的访问权限。
- 复合角色
-
复合角色是可以与其他角色关联的角色。例如,
superuser
复合角色可以与sales-admin
和order-entry-admin
角色关联。如果用户映射到superuser
角色,他们也会继承sales-admin
和order-entry-admin
角色。 - 组
-
组管理用户组。可以为组定义属性。您也可以将角色映射到组。成为组成员的用户将继承该组定义的属性和角色映射。
- 域
-
域管理一组用户、凭据、角色和组。用户属于并登录到一个域。域彼此隔离,并且只能管理和验证他们控制的用户。
- 客户端
-
客户端是可以请求 Keycloak 验证用户身份的实体。通常,客户端是想要使用 Keycloak 来保护自身并提供单点登录解决方案的应用程序和服务。客户端也可以是只想请求身份信息或访问令牌的实体,以便他们可以安全地调用网络上由 Keycloak 保护的其他服务。
- 客户端适配器
-
客户端适配器是您安装到应用程序环境中的插件,以便能够与 Keycloak 通信并受其保护。Keycloak 具有许多适用于不同平台的适配器,您可以下载这些适配器。还有您可以为我们未涵盖的环境获得的第三方适配器。
- 同意
-
同意是指当您作为管理员希望用户在客户端参与身份验证过程之前向客户端授予权限时。在用户提供其凭据后,Keycloak 将弹出一个屏幕,标识请求登录的客户端以及向用户请求的身份信息。用户可以决定是否授予请求。
- 客户端作用域
-
注册客户端时,您必须为该客户端定义协议映射器和角色作用域映射。存储客户端作用域通常很有用,通过共享一些常用设置,可以更轻松地创建新客户端。这对于根据
scope
参数的值有条件地请求某些声明或角色也很有用。Keycloak 为此提供了客户端作用域的概念。 - 客户端角色
-
客户端可以定义特定于它们的角色。这基本上是专用于客户端的角色命名空间。
- 身份令牌
-
提供有关用户身份信息的令牌。OpenID Connect 规范的一部分。
- 访问令牌
-
可以作为 HTTP 请求的一部分提供的令牌,该令牌授予对正在调用的服务的访问权限。这是 OpenID Connect 和 OAuth 2.0 规范的一部分。
- 断言
-
有关用户的信息。这通常与包含在 SAML 身份验证响应中的 XML blob 有关,该响应提供了有关已验证用户的身份元数据。
- 服务帐户
-
每个客户端都有一个内置的服务帐户,允许它获取访问令牌。
- 直接授权
-
客户端代表用户通过 REST 调用获取访问令牌的一种方式。
- 协议映射器
-
对于每个客户端,您都可以定制存储在 OIDC 令牌或 SAML 断言中的声明和断言。您可以通过创建和配置协议映射器来为每个客户端执行此操作。
- 会话
-
当用户登录时,会创建一个会话来管理登录会话。会话包含诸如用户何时登录以及哪些应用程序在该会话期间参与了单点登录的信息。管理员和用户都可以查看会话信息。
- 用户联合提供商
-
Keycloak 可以存储和管理用户。通常,公司已经拥有 LDAP 或 Active Directory 服务,用于存储用户和凭据信息。您可以将 Keycloak 指向这些外部存储以验证凭据并提取身份信息。
- 身份提供商
-
身份提供商 (IDP) 是一种可以验证用户身份的服务。Keycloak 就是一个 IDP。
- 身份提供商联合
-
Keycloak 可以配置为将身份验证委派给一个或多个 IDP。通过 Facebook 或 Google 进行社交登录是身份提供商联合的一个示例。您还可以连接 Keycloak 以将身份验证委派给任何其他 OpenID Connect 或 SAML 2.0 IDP。
- 身份提供商映射器
-
在执行 IDP 联合时,您可以将传入的令牌和断言映射到用户和会话属性。这有助于您将身份信息从外部 IDP 传播到请求身份验证的客户端。
- 必需操作
-
必需操作是用户在身份验证过程中必须执行的操作。用户在完成这些操作之前将无法完成身份验证过程。例如,管理员可以安排用户每月重置其密码。将为所有这些用户设置
update password
必需操作。 - 身份验证流程
-
身份验证流程是用户在与系统的某些方面交互时必须执行的工作流程。登录流程可以定义所需的凭据类型。注册流程定义用户必须输入的个人资料信息以及是否必须使用 reCAPTCHA 等来过滤掉机器人程序。凭据重置流程定义用户在重置密码之前必须执行的操作。
- 事件
-
事件是管理员可以查看和挂钩的审计流。
- 主题
-
Keycloak 提供的每个屏幕都由一个主题支持。主题定义 HTML 模板和样式表,您可以根据需要覆盖它们。
创建第一个管理员
安装 Keycloak 后,您需要一个管理员帐户,该帐户可以充当超级管理员,并具有管理 Keycloak 的完全权限。使用此帐户,您可以登录到 Keycloak 管理控制台,您可以在其中创建域和用户,并注册由 Keycloak 保护的应用程序。
在本地主机上创建帐户
如果您的服务器可以从 localhost
访问,请执行以下步骤。
-
在 Web 浏览器中,转到 https://#:8080 URL。
-
提供您可以记住的用户名和密码。
欢迎页面
配置域
一旦您拥有管理员控制台的管理员帐户,您就可以配置域。域是您管理对象(包括用户、应用程序、角色和组)的空间。用户属于并登录到一个域。一个 Keycloak 部署可以定义、存储和管理任意数量的域,只要数据库中有足够的空间。
使用管理控制台
您可以在 Keycloak 管理控制台中配置域并执行大多数管理任务。
要使用管理控制台,您需要一个管理员帐户。
-
如果不存在管理员,请参阅创建第一个管理员。
-
如果存在其他管理员,请让管理员提供具有管理域权限的帐户。
-
转到管理控制台的 URL。
例如,对于 localhost,请使用此 URL:https://#:8080/admin/
-
输入您在欢迎页面上创建的用户名和密码,或通过环境变量创建的用户名和密码,如创建初始管理员用户中所述。
登录页面此操作将显示管理控制台。
管理控制台 -
注意您可以使用的菜单和其他选项
-
单击当前域以查看是否有其他域可供管理。
-
单击创建域以创建另一个您可以管理的域。
-
单击右上角的列表以查看您的帐户或注销。
-
-
单击菜单中的域设置以查看此域的字段和选项。
单击问号 ? 图标以显示字段的定义,例如前端 URL。
域设置
从管理控制台导出的文件不适合备份或服务器之间的数据传输。只有启动时导出才适合备份或服务器之间的数据传输。 |
主 Realm
在管理控制台中,存在两种类型的 realm
-
Master realm
- 此 realm 是您首次启动 Keycloak 时为您创建的。它包含您在首次登录时创建的管理员帐户。仅使用 master realm 来创建和管理系统中的 realm。 -
Other realms
- 这些 realm 由 master realm 中的管理员创建。在这些 realm 中,管理员管理您组织中的用户以及他们需要的应用程序。应用程序归用户所有。
Realm 彼此隔离,并且只能管理和验证他们控制的用户。遵循此安全模型有助于防止意外更改,并遵循传统,即仅允许用户帐户访问成功完成当前任务所需的特权和权力。
-
如果您想禁用 master realm 并在您创建的任何新 realm 中定义管理员帐户,请参阅 Dedicated Realm Admin Consoles。每个 realm 都有其自己专用的管理控制台,您可以使用本地帐户登录。
创建 realm
您创建 realm 以提供管理空间,您可以在其中创建用户并授予他们使用应用程序的权限。首次登录时,您通常在 master realm 中,这是您从中创建其他 realm 的顶级 realm。
在决定您需要哪些 realm 时,请考虑您希望为您的用户和应用程序提供的隔离类型。例如,您可以为贵公司的员工创建一个 realm,并为您的客户创建一个单独的 realm。您的员工将登录到员工 realm,并且只能访问内部公司应用程序。客户将登录到客户 realm,并且只能与面向客户的应用程序进行交互。
-
在管理控制台中,单击“当前 realm”旁边的“创建 Realm”。
-
输入 realm 的名称。
-
单击“创建”。
创建 realm当前 realm 现在设置为您刚刚创建的 realm。您可以通过单击菜单中的 realm 名称在 realm 之间切换。
为 realm 配置 SSL
每个 realm 都有一个关联的 SSL 模式,该模式定义了与 realm 交互的 SSL/HTTPS 要求。与 realm 交互的浏览器和应用程序必须遵守 SSL 模式定义的 SSL/HTTPS 要求,否则它们无法与服务器交互。
-
在菜单中单击“Realm 设置”。
-
单击“常规”选项卡。
常规选项卡 -
将“需要 SSL”设置为以下 SSL 模式之一
-
外部请求 - 只要用户坚持使用私有 IPv4 地址(例如
localhost
、127.0.0.1
、10.x.x.x
、192.168.x.x
、172.16.x.x
)或 IPv6 链路本地地址和唯一本地地址,用户就可以在没有 SSL 的情况下与 Keycloak 交互。如果您尝试从非私有 IP 地址在没有 SSL 的情况下访问 Keycloak,您将收到错误。 -
无 - Keycloak 不需要 SSL。此选项仅适用于您在进行实验且不计划支持此部署的开发环境。
-
所有请求 - Keycloak 要求所有 IP 地址都使用 SSL。
-
为 realm 配置电子邮件
Keycloak 向用户发送电子邮件以验证他们的电子邮件地址、在他们忘记密码时或当管理员需要接收有关服务器事件的通知时。要使 Keycloak 能够发送电子邮件,您需要为 Keycloak 提供您的 SMTP 服务器设置。
-
在菜单中单击“Realm 设置”。
-
单击“电子邮件”选项卡。
电子邮件选项卡 -
填写字段并根据需要切换开关。
- 发件人
-
发件人”表示用于发送电子邮件的 From SMTP 标头的地址。
- 发件人显示名称
-
发件人显示名称”允许配置用户友好的电子邮件地址别名(可选)。如果未设置,则将在电子邮件客户端中显示纯 发件人 电子邮件地址。
- 回复至
-
回复至”表示用于发送邮件的 Reply-To SMTP 标头的地址(可选)。如果未设置,则将使用纯 发件人 电子邮件地址。
- 回复至显示名称
-
回复至显示名称”允许配置用户友好的电子邮件地址别名(可选)。如果未设置,则将显示纯 回复至 电子邮件地址。
- 邮件信封发件人
-
邮件信封发件人”表示用于发送邮件的 Return-Path SMTP 标头的 退回地址(可选)。
- 主机
-
主机”表示用于发送电子邮件的 SMTP 服务器主机名。
- 端口
-
端口”表示 SMTP 服务器端口。
- 加密
-
勾选其中一个复选框以支持发送用于恢复用户名和密码的电子邮件,特别是当 SMTP 服务器位于外部网络上时。您很可能需要将“端口”更改为 465,这是 SSL/TLS 的默认端口。
- 身份验证
-
如果您的 SMTP 服务器需要身份验证,请将此开关设置为“开启”。
- 用户名
-
所有身份验证机制都需要用户名。
- 身份验证类型
-
选择身份验证的类型:“password”或“token”。
- 密码
-
仅当选择“身份验证类型”为“password”时才需要。提供 密码。“密码”字段的值可以引用来自外部 vault 的值。
- 身份验证令牌 URL
-
仅当选择“身份验证类型”为“token”时才需要。提供用于通过客户端凭据授权获取令牌的 身份验证令牌 URL。
- 身份验证令牌范围
-
仅当选择“身份验证类型”为“token”时才需要。提供用于从 身份验证令牌 URL 获取令牌的 身份验证令牌范围。
- 身份验证令牌客户端 ID
-
仅当选择“身份验证类型”为“token”时才需要。提供用于从 身份验证令牌 URL 获取令牌的 身份验证客户端 ID。
- 身份验证令牌客户端密钥
-
仅当选择“身份验证类型”为“token”时才需要。提供用于验证客户端身份以从 身份验证令牌 URL 获取令牌的 身份验证客户端密钥。“身份验证客户端密钥”字段的值可以引用来自外部 vault 的值。
使用第三方供应商进行 XOAUTH2 电子邮件配置
以下部分包含关于如何配置 Keycloak 电子邮件设置以将 XOAUTH2 身份验证与一些已知的第三方软件 SMTP 服务器一起使用的提示。
本节由 Keycloak 社区贡献。由于 Keycloak 核心团队没有测试第三方提供商的手段,因此按原样提供。如果您发现本文档已过时或不完整,请贡献以改进它。 |
Microsoft Azure 和 Office365 的配置
Microsoft Azure 允许使用客户端密钥的“客户端凭据授权”来收集访问令牌。Microsoft Office365 支持使用 XOAUTH2 的 SMTP 来使用收集的令牌进行身份验证。
相关 Microsoft 文档的链接
以下用于设置 Keycloak 以使用 Azure 和 Office365 发送电子邮件的方法已通过测试验证。根据您的环境,可能还有其他变体可以实现相同的目的。
- 发件人
-
<some>@<domain>
- 主机
-
smtp.office365.com
- 端口
-
587
- 加密
-
选中“启动 TLS”
- 用户名
-
<some>@<domain>
(可能与发件人值相同或不同) - 身份验证令牌 URL
-
https://login.microsoftonline.com/<TenantID>/oauth2/v2.0/token
将 TenantID 替换为您的 Microsoft 租户的 ID(通常是 UUID),在 Azure 中,或者只需从 Azure 控制台中显示的端点列表中复制令牌 URL。
- 身份验证令牌范围
-
https://outlook.office.com/.default
- 身份验证令牌客户端 ID
-
<ApplicationId>
将 ApplicationId 替换为您的应用程序在 Azure 中的 ID(通常是 UUID)。
- 身份验证令牌客户端密钥
-
<Secret configured>
配置主题
对于给定的 realm,您可以使用主题更改 Keycloak 中任何 UI 的外观。
-
在菜单中单击“Realm 设置”。
-
单击“主题”选项卡。
主题选项卡 -
为每个 UI 类别选择您想要的主题,然后单击“保存”。
- 登录主题
-
用户名密码输入、OTP 输入、新用户注册以及其他与登录相关的类似屏幕。
- 帐户主题
-
用户用于管理其帐户的控制台。
- 管理控制台主题
-
Keycloak 管理控制台的皮肤。
- 电子邮件主题
-
每当 Keycloak 必须发送电子邮件时,它都会使用此主题中定义的模板来制作电子邮件。
-
《服务器开发人员指南》介绍了如何创建新主题或修改现有主题。
启用国际化
Keycloak 中的每个 UI 屏幕都已国际化。默认语言为英语,但您可以选择要支持的语言环境以及默认语言环境。
-
在菜单中单击“Realm 设置”。
-
单击“本地化”选项卡。
-
启用“国际化”。
-
选择您将支持的语言。
本地化选项卡用户下次登录时,可以在登录页面上选择一种语言,用于登录屏幕、帐户控制台和管理控制台。
-
《服务器开发人员指南》解释了如何提供其他语言。主题提供的所有国际化文本都可以被“本地化”选项卡上的 realm 特定文本覆盖。
用户语言环境选择
语言环境选择器提供程序根据可用信息建议最佳语言环境。但是,通常不知道用户是谁。因此,先前经过身份验证的用户的语言环境会保存在持久性 Cookie 中。
选择语言环境的逻辑使用以下可用的第一个选项
-
用户选择 - 当用户使用下拉语言环境选择器选择了一个语言环境时
-
用户配置文件 - 当存在经过身份验证的用户并且用户设置了首选语言环境时
-
客户端选择 - 由客户端传递,例如使用 ui_locales 参数
-
Cookie - 浏览器上最后选择的语言环境
-
接受的语言 - 来自 Accept-Language 标头的语言环境
-
Realm 默认
-
如果以上都不是,则回退到英语
当用户通过身份验证时,会触发一个操作来更新前面提到的持久 cookie 中的语言环境。如果用户在登录页面上通过语言环境选择器主动切换了语言环境,则用户的语言环境也会在此处更新。
如果您想更改选择语言环境的逻辑,您可以选择创建自定义的 LocaleSelectorProvider
。有关详细信息,请参阅 服务器开发指南。
控制登录选项
Keycloak 包含多个内置登录页面功能。
启用忘记密码
如果您启用 忘记密码
,用户可以在忘记密码或丢失 OTP 生成器时重置其登录凭据。
-
在菜单中单击“Realm 设置”。
-
点击 登录 选项卡。
登录选项卡 -
将 忘记密码 切换为 开启。
忘记密码?
链接将显示在您的登录页面中。忘记密码链接 -
在 电子邮件 选项卡中指定
主机
和发件人
,以便 Keycloak 能够发送重置电子邮件。 -
点击此链接将用户带到他们可以输入用户名或电子邮件地址的地方,并收到一封包含重置凭据链接的电子邮件。
忘记密码页面
电子邮件中发送的文本是可配置的。有关更多信息,请参阅 服务器开发指南。
当用户点击电子邮件链接时,Keycloak 会要求他们更新密码;如果他们设置了 OTP 生成器,Keycloak 会要求他们重新配置 OTP 生成器。出于安全原因,该流程强制联合用户在重置凭据后重新登录,如果使用相同的身份验证会话(同一浏览器),则内部数据库用户保持登录状态。根据您组织的安全要求,您可以更改默认行为。
要更改此行为,请执行以下步骤
-
点击菜单中的 身份验证。
-
点击 流程 选项卡。
-
选择 重置凭据 流程。
重置凭据流程如果您不想重置 OTP,请将
重置 - 条件 OTP
子流程要求设置为 禁用。发送重置电子邮件配置如果您想更改强制登录选项的默认行为,请点击流程中的 发送重置电子邮件 设置图标,定义一个 别名,并为您选择最佳的 重置后强制登录 选项(
true
,始终强制重新身份验证,false
,如果使用相同的浏览器,则保持用户登录状态,only-federated
,默认值,仅强制联合用户再次登录)。 -
点击菜单中的 身份验证。
-
点击 必需操作 选项卡。
-
确保 更新密码 已启用。
必需操作
启用记住我
已登录用户关闭浏览器会销毁他们的会话,该用户必须重新登录。您可以设置 Keycloak 以保持用户的登录会话打开,如果该用户在登录时点击了记住我复选框。此操作将登录 cookie 从仅会话 cookie 转换为持久 cookie。
-
在菜单中单击“Realm 设置”。
-
点击 登录 选项卡。
-
将 记住我 开关切换为 开启。
登录选项卡当您保存此设置时,
记住我
复选框将显示在 realm 的登录页面上。记住我
ACR 到身份验证级别 (LoA) 映射
在 realm 的常规设置中,您可以定义哪个 身份验证上下文类引用 (ACR)
值映射到哪个 身份验证级别 (LoA)
。ACR 可以是任何值,而 LoA 必须是数字。acr 声明可以在 OIDC 请求中发送的 claims
或 acr_values
参数中请求,并且它也包含在访问令牌和 ID 令牌中。映射的数字用于身份验证流程条件中。
如果特定客户端需要使用与 realm 不同的值,则也可以在客户端级别指定映射。但是,最佳实践是坚持 realm 映射。
有关更多详细信息,请参阅 逐步验证 和 官方 OIDC 规范。
更新电子邮件工作流程 (UpdateEmail)
使用此工作流程,用户将必须使用 UPDATE_EMAIL 操作来更改自己的电子邮件地址。
此操作与单个电子邮件输入表单关联。如果 realm 禁用了电子邮件验证,则此操作将允许在不进行验证的情况下更新电子邮件。如果 realm 启用了电子邮件验证,则此操作将向新电子邮件地址发送电子邮件更新操作令牌,而无需更改帐户电子邮件。只有操作令牌触发才会完成电子邮件更新。
应用程序可以通过利用 UPDATE_EMAIL 作为 AIA(应用程序启动的操作) 将其用户发送到电子邮件更新表单。
UpdateEmail 是 预览版,尚未完全支持。此功能默认情况下处于禁用状态。 要启用,请使用 |
如果您启用此功能并且正在从以前的版本迁移,请在您的 realm 中启用 更新电子邮件 必需操作。否则,用户将无法更新其电子邮件地址。 |
配置 realm 密钥
Keycloak 使用的身份验证协议需要加密签名,有时还需要加密。Keycloak 使用非对称密钥对(私钥和公钥)来实现这一点。
Keycloak 一次只有一个活动密钥对,但也可以有多个被动密钥。活动密钥对用于创建新签名,而被动密钥对可用于验证以前的签名。这使得定期轮换密钥成为可能,而不会对用户造成任何停机或中断。
创建 realm 时,会自动生成密钥对和自签名证书。
-
在菜单中单击“Realm 设置”。
-
点击 密钥。
-
从过滤器下拉列表中选择 被动密钥 以查看被动密钥。
-
从过滤器下拉列表中选择 禁用密钥 以查看禁用密钥。
密钥对可能具有 活动
状态,但仍未被选为 realm 当前的活动密钥对。用于签名的选定活动密钥对是根据优先级排序的第一个能够提供活动密钥对的密钥提供程序来选择的。
轮换密钥
我们建议您定期轮换密钥。首先创建优先级高于现有活动密钥的新密钥。您可以改为创建优先级相同的新密钥,并将之前的密钥设为被动密钥。
一旦新密钥可用,所有新令牌和 cookie 都将使用新密钥签名。当用户向应用程序进行身份验证时,SSO cookie 将使用新签名进行更新。当 OpenID Connect 令牌刷新时,新令牌将使用新密钥签名。最终,所有 cookie 和令牌都使用新密钥,一段时间后可以删除旧密钥。
删除旧密钥的频率是在安全性和确保所有 cookie 和令牌都更新之间进行权衡。考虑每三到六个月创建新密钥,并在创建新密钥后一到两个月删除旧密钥。如果用户在新密钥添加和旧密钥删除之间的时间段内处于非活动状态,则该用户将必须重新进行身份验证。
轮换密钥也适用于离线令牌。为了确保它们被更新,应用程序需要在旧密钥被删除之前刷新令牌。
添加生成的密钥对
使用此过程生成密钥对,包括自签名证书。
-
在管理控制台中选择 realm。
-
在菜单中单击“Realm 设置”。
-
点击 密钥 选项卡。
-
点击 提供程序 选项卡。
-
点击 添加提供程序 并选择 rsa-generated。
-
在 优先级 字段中输入一个数字。此数字决定新密钥对是否成为活动密钥对。数字越大,密钥对越活跃。
-
为 AES 密钥大小 选择一个值。
-
点击 保存。
更改提供程序的优先级不会导致密钥重新生成,但如果您想更改密钥大小,您可以编辑提供程序,然后将生成新密钥。
通过提取证书轮换密钥
您可以通过从 RSA 生成的密钥对中提取证书,并在新的密钥库中使用该证书来轮换密钥。
-
生成的密钥对
-
在管理控制台中选择 realm。
-
点击 Realm 设置。
-
点击 密钥 选项卡。
将显示 活动 密钥列表。
-
在带有 RSA 密钥的行上,点击 公钥 下的 证书。
证书以文本形式显示。
-
将证书保存到文件,并将其括在以下行中。
----Begin Certificate---- <Output> ----End Certificate----
-
使用 keytool 命令将密钥文件转换为 PEM 格式。
-
从密钥库中删除当前的 RSA 公钥证书。
keytool -delete -keystore <keystore>.jks -storepass <password> -alias <key>
-
将新证书导入到密钥库中
keytool -importcert -file domain.crt -keystore <keystore>.jks -storepass <password> -alias <key>
-
重新构建应用程序。
mvn clean install wildfly:deploy
添加现有密钥对和证书
要添加从其他地方获得的密钥对和证书,请选择 提供程序
并从下拉列表中选择 rsa
。您可以更改优先级以确保新密钥对成为活动密钥对。
-
私钥文件。该文件必须是 PEM 格式。
-
在管理控制台中选择 realm。
-
点击 Realm 设置。
-
点击 密钥 选项卡。
-
点击 提供程序 选项卡。
-
点击 添加提供程序 并选择 rsa。
-
在 优先级 字段中输入一个数字。此数字决定新密钥对是否成为活动密钥对。
-
点击 浏览… 旁边的 私有 RSA 密钥 以上传私钥文件。
-
如果您有私钥的签名证书,请点击 浏览… 旁边的 X509 证书 以上传证书文件。如果您不上传证书,Keycloak 会自动生成自签名证书。
-
点击 保存。
从 Java 密钥库加载密钥
要添加存储在主机上的 Java 密钥库文件中的密钥对和证书,请选择 提供程序
并从下拉列表中选择 java-keystore
。您可以更改优先级以确保新密钥对成为活动密钥对。
为了加载关联的证书链,必须使用用于加载密钥对的相同 密钥别名
将其导入到 Java 密钥库文件中。
-
在管理控制台中选择 realm。
-
在菜单中单击“Realm 设置”。
-
点击 密钥 选项卡。
-
点击 提供程序 选项卡。
-
点击 添加提供程序 并选择 java-keystore。
-
在 优先级 字段中输入一个数字。此数字决定新密钥对是否成为活动密钥对。
-
输入所需的 算法。请注意,该算法应与密钥类型匹配(例如,
RS256
需要 RSA 私钥,ES256
需要 EC 私钥,AES
需要 AES 密钥)。 -
输入 密钥库 的值。密钥库文件的路径。
-
输入密钥库密码。此选项可以引用来自外部密钥库的值。
-
输入密钥库类型的值(
JKS
、PKCS12
或BCFKS
)。 -
输入要从密钥库加载的密钥别名的值。
-
输入密钥密码。此选项可以引用来自外部密钥库的值。
-
输入密钥用途的值(
sig
用于签名,或enc
用于加密)。请注意,用途应与算法类型匹配(例如,RS256
是sig
,但RSA-OAEP
是enc
)。 -
点击 保存。
并非所有密钥库类型都支持所有类型的密钥。例如,所有模式下的 |
使密钥被动
-
在管理控制台中选择 realm。
-
在菜单中单击“Realm 设置”。
-
点击 密钥 选项卡。
-
点击 提供程序 选项卡。
-
单击要使其被动的密钥的提供程序。
-
将活动切换为关闭。
-
点击 保存。
禁用密钥
-
在管理控制台中选择 realm。
-
在菜单中单击“Realm 设置”。
-
点击 密钥 选项卡。
-
点击 提供程序 选项卡。
-
单击要使其被动的密钥的提供程序。
-
将已启用切换为关闭。
-
点击 保存。
泄露的密钥
Keycloak 将签名密钥仅本地存储,并且永远不会与客户端应用程序、用户或其他实体共享。但是,如果您认为您的 realm 签名密钥已泄露,您应首先生成新的密钥对(如上所述),然后立即删除泄露的密钥对。
或者,您可以从 Providers
表中删除提供程序。
-
单击菜单中的 Clients(客户端)。
-
单击 security-admin-console。
-
向下滚动到 Access settings(访问设置)部分。
-
填写 Admin URL(管理 URL)字段。
-
单击 Advanced(高级)选项卡。
-
在 Revocation(吊销)部分中,单击 Set to now(设置为现在)。
-
单击 Push(推送)。
推送 not-before 策略可确保客户端应用程序不接受由泄露的密钥签名的现有令牌。客户端应用程序也被迫从 Keycloak 下载新的密钥对,因此由泄露的密钥签名的令牌将无效。
REST 和保密客户端必须设置 Admin URL,以便 Keycloak 可以向客户端发送推送的 not-before 策略请求。 |
使用外部存储
组织可能拥有包含信息、密码和其他凭据的数据库。通常,您无法将现有数据存储迁移到 Keycloak 部署,因此 Keycloak 可以联合现有外部用户数据库。Keycloak 支持 LDAP 和 Active Directory,但您也可以通过使用 Keycloak User Storage SPI 为任何自定义用户数据库编写扩展。
当用户尝试登录时,Keycloak 会检查该用户的存储以查找该用户。如果 Keycloak 未找到该用户,Keycloak 会迭代 realm 的每个用户存储提供程序,直到找到匹配项。然后,来自外部数据存储的数据会映射到 Keycloak 运行时使用的标准用户模型中。然后,此用户模型会映射到 OIDC 令牌声明和 SAML 断言属性。
外部用户数据库很少具有支持 Keycloak 所有功能所需的数据,因此用户存储提供程序可以选择在 Keycloak 用户数据存储中本地存储项目。提供程序可以本地导入用户并定期与外部数据存储同步。此方法取决于提供程序的功能和提供程序的配置。例如,您的外部用户数据存储可能不支持 OTP。OTP 可以由 Keycloak 处理和存储,具体取决于提供程序。
添加提供程序
要添加存储提供程序,请执行以下步骤
-
单击菜单中的 User Federation(用户联合)。
用户联合 -
选择添加 Kerberos 或 LDAP 提供程序
Keycloak 将您带到该提供程序的配置页面。
处理提供程序故障
如果用户存储提供程序失败,您可能无法登录和查看管理控制台中的用户。当使用存储提供程序查找用户时,Keycloak 不会检测到故障,因此它会取消调用。如果您有一个高优先级的存储提供程序在用户查找期间失败,则登录或用户查询将因异常而失败,并且不会故障转移到下一个配置的提供程序。
Keycloak 首先搜索本地 Keycloak 用户数据库以解析用户,然后再搜索任何 LDAP 或自定义用户存储提供程序。考虑在本地 Keycloak 用户数据库中创建一个管理员帐户,以防连接到您的 LDAP 和后端时出现问题。
每个 LDAP 和自定义用户存储提供程序在其管理控制台页面上都有一个 enable
(启用)切换开关。禁用用户存储提供程序会在执行查询时跳过该提供程序,因此您可以使用较低优先级的不同提供程序中的用户帐户查看和登录。如果您的提供程序使用 import
(导入)策略并且已禁用,则导入的用户仍然可以只读模式进行查找。
当存储提供程序查找失败时,Keycloak 不会进行故障转移,因为用户数据库通常在它们之间具有重复的用户名或重复的电子邮件。重复的用户名和电子邮件可能会导致问题,因为当管理员希望用户从另一个数据存储加载时,用户却从一个外部数据存储加载。
轻型目录访问协议 (LDAP) 和 Active Directory
Keycloak 包含 LDAP/AD 提供程序。您可以在一个 Keycloak realm 中联合多个不同的 LDAP 服务器,并将 LDAP 用户属性映射到 Keycloak 通用用户模型中。
默认情况下,Keycloak 映射用户名、电子邮件、名字和姓氏,但您也可以配置其他映射器。Keycloak 的 LDAP/AD 提供程序支持使用 LDAP/AD 协议和存储、编辑和同步模式进行密码验证。
配置联合 LDAP 存储
-
单击菜单中的 User Federation(用户联合)。
用户联合 -
单击 Add LDAP providers(添加 LDAP 提供程序)。
Keycloak 将您带到 LDAP 配置页面。
添加 LDAP 提供程序
存储模式
Keycloak 将用户从 LDAP 导入到本地 Keycloak 用户数据库。用户数据库的此副本按需或通过定期后台任务同步。密码同步存在例外。Keycloak 永远不会导入密码。密码验证始终在 LDAP 服务器上进行。
同步的优势在于,所有 Keycloak 功能都可以高效工作,因为任何所需的额外每用户数据都本地存储。缺点是每次 Keycloak 首次查询特定用户时,Keycloak 都会执行相应的数据库插入。此外,当导入的用户作为搜索操作的一部分返回时,将为每个用户执行相应的 LDAP 搜索,以检查用户是否仍然存在于 LDAP 中并进行一些基本验证。
您可以将导入与 LDAP 服务器同步。当 LDAP 映射器始终从 LDAP 而不是数据库读取特定属性时,导入同步是不必要的。
您可以将 LDAP 与 Keycloak 一起使用,而无需将用户导入到 Keycloak 用户数据库中。LDAP 服务器备份 Keycloak 运行时使用的通用用户模型。如果 LDAP 不支持 Keycloak 功能所需的数据,则该功能将无法工作。这种方法的优点是您没有导入和同步 LDAP 用户副本到 Keycloak 用户数据库的资源消耗。
LDAP 配置页面上的 Import Users(导入用户)开关控制此存储模式。要导入用户,请将此开关切换为 ON(开启)。
如果您禁用 Import Users(导入用户),则无法将用户配置文件属性保存到 Keycloak 数据库中。此外,除了映射到 LDAP 的用户配置文件元数据外,您也无法保存元数据。此元数据可以包括角色映射、组映射和其他基于 LDAP 映射器配置的元数据。 当您尝试更改非 LDAP 映射的用户数据时,用户更新是不可能的。例如,您无法禁用 LDAP 映射的用户,除非用户的 |
当处理导入的用户时,当查询用户以验证用户并对其进行修饰以使配置的映射器正常工作时,Keycloak 会执行 LDAP 搜索。这意味着在执行可能获取大量用户的未过滤用户搜索时必须格外小心,因为将为找到的每个导入用户发出 LDAP 搜索,这可能会对性能产生负面影响。 获取单个用户(例如在登录期间)的操作通常会被缓存,并且不应受到首次获取用户时执行的额外 LDAP 搜索的影响。 |
编辑模式
用户和管理员可以修改用户元数据,用户通过帐户控制台,管理员通过管理控制台。LDAP 配置页面上的 Edit Mode
(编辑模式)配置定义了用户的 LDAP 更新权限。
- READONLY(只读)
-
您无法更改用户名、电子邮件、名字、姓氏和其他映射的属性。每当用户尝试更新这些字段时,Keycloak 都会显示错误。不支持密码更新。
- WRITABLE(可写)
-
您可以更改用户名、电子邮件、名字、姓氏和其他映射的属性和密码,并将它们自动与 LDAP 存储同步。
- UNSYNCED(未同步)
-
Keycloak 将对用户名、电子邮件、名字、姓氏和密码的更改存储在 Keycloak 本地存储中,因此管理员必须将此数据同步回 LDAP。在此模式下,Keycloak 部署可以更新只读 LDAP 服务器上的用户元数据。当从 LDAP 导入用户到本地 Keycloak 用户数据库时,此选项也适用。
当 Keycloak 创建 LDAP 提供程序时,Keycloak 还会创建一组初始LDAP 映射器。Keycloak 根据 Vendor(供应商)、Edit Mode(编辑模式)和 Import Users(导入用户)开关的组合来配置这些映射器。例如,当编辑模式为 UNSYNCED(未同步)时,Keycloak 配置映射器以从数据库而不是 LDAP 服务器读取特定用户属性。但是,如果您稍后更改编辑模式,映射器的配置不会更改,因为无法检测到配置更改是否在 UNSYNCED(未同步)模式下更改。在创建 LDAP 提供程序时决定 Edit Mode(编辑模式)。此说明也适用于 Import Users(导入用户)开关。 |
其他配置选项
- Console Display Name(控制台显示名称)
-
要在管理控制台中显示的提供程序的名称。
- Priority(优先级)
-
查找用户或添加用户时提供程序的优先级。
- Sync Registrations(同步注册)
-
如果您希望将 Keycloak 创建的新用户添加到 LDAP,请将此开关切换为 ON(开启)。
- Allow Kerberos authentication(允许 Kerberos 身份验证)
-
在 realm 中启用 Kerberos/SPNEGO 身份验证,用户数据从 LDAP 提供。有关更多信息,请参阅Kerberos 部分。
- Remove invalid users during searches(在搜索期间删除无效用户)
-
如果用户存储中没有用户,则在执行搜索时从本地数据库中删除用户。如果为 true,则每当尝试查找用户时,将从本地数据库中删除不再从其相应的用户存储中可用的用户。如果为 false,则先前从用户存储导入的用户将保留在本地数据库中,作为只读和禁用状态,即使该用户不再从用户存储中可用。例如,用户直接从 LDAP 中删除,或者
Users DN
无效。请注意,此行为仅在用户尚未缓存时才会发生。 - Relative User Creation DN(相对用户创建 DN)
-
新用户将在其中创建的
Users DN
的相对 DN。当使用subtree
(子树)搜索范围时,这允许在父Users DN
的子 DN 中创建用户。例如,如果Users DN
设置为ou=people,dc=myorg,dc=com
,并且Relative User Creation DN
设置为ou=engineering
,则将从Users DN
和所有子 DN 中获取用户,但新用户将存储在ou=engineering,ou=people,dc=myorg,dc=com
中。换句话说,Keycloak 将Relative User Creation DN
与Users DN
连接(在连接 DN 时会自动添加逗号),并使用此结果 DN 来存储用户
组和角色映射器中也提供了类似的属性,允许将组和角色添加到用于搜索组/角色的基本 DN 的子 DN 中。
- 其他选项
-
将鼠标指针悬停在管理控制台中的工具提示上,以查看有关这些选项的更多详细信息。
通过 SSL 连接到 LDAP
当您为 LDAP 存储配置安全连接 URL(例如,ldaps://myhost.com:636
)时,Keycloak 使用 SSL 与 LDAP 服务器通信。在 Keycloak 服务器端配置信任存储,以便 Keycloak 可以信任与 LDAP 的 SSL 连接 - 请参阅配置信任存储指南。
Use Truststore SPI
配置属性已弃用。通常应将其保留为 Always
(始终)。
将 LDAP 用户同步到 Keycloak
如果您设置 Import Users(导入用户)选项,LDAP 提供程序将处理将 LDAP 用户导入到 Keycloak 本地数据库中。当用户首次登录或作为用户查询的一部分返回时(例如,使用管理控制台中的搜索字段),LDAP 提供程序会将 LDAP 用户导入到 Keycloak 数据库中。在身份验证期间,将验证 LDAP 密码。
如果您想将所有 LDAP 用户同步到 Keycloak 数据库中,请在 LDAP 提供程序配置页面上配置并启用 Sync Settings(同步设置)。
存在两种类型的同步
- Periodic Full sync(定期完全同步)
-
此类型将所有 LDAP 用户同步到 Keycloak 数据库中。Keycloak 中已存在但在 LDAP 中不同的 LDAP 用户将直接在 Keycloak 数据库中更新。
- 定期更改的用户同步
-
同步时,Keycloak 仅创建或更新自上次同步后创建或更新的用户。
最佳同步方式是在首次创建 LDAP 提供程序时单击同步所有用户,然后设置定期同步更改的用户。
LDAP 映射器
LDAP 映射器是由 LDAP 提供程序触发的 listeners
(监听器)。它们为 LDAP 集成提供了另一个扩展点。LDAP 映射器在以下情况下被触发:
-
用户通过使用 LDAP 登录。
-
用户首次注册。
-
管理员控制台查询用户。
当您创建 LDAP 联合提供程序时,Keycloak 会自动为此提供程序提供一组 mappers
(映射器)。用户可以更改此集合,用户还可以开发映射器或更新/删除现有映射器。
- 用户属性映射器
-
此映射器指定哪个 LDAP 属性映射到 Keycloak 用户的属性。例如,您可以将
mail
LDAP 属性配置为 Keycloak 数据库中的email
属性。对于此映射器实现,始终存在一对一映射。 - 全名映射器
-
此映射器指定用户的全名。Keycloak 将名称保存在 LDAP 属性(通常为
cn
)中,并将该名称映射到 Keycloak 数据库中的firstName
和lastname
属性。对于 LDAP 部署,cn
包含用户的全名是很常见的。
当您在 Keycloak 中注册新用户且 LDAP 提供程序的 |
- 硬编码属性映射器
-
此映射器将硬编码的属性值添加到链接到 LDAP 的每个 Keycloak 用户。此映射器还可以强制设置
enabled
或emailVerified
用户属性的值。 - 角色映射器
-
此映射器配置从 LDAP 到 Keycloak 角色映射的角色映射。单个角色映射器可以将 LDAP 角色(通常是来自 LDAP 树特定分支的组)映射到与指定客户端的领域角色或客户端角色对应的角色。您可以为同一 LDAP 提供程序配置多个角色映射器。例如,您可以指定来自
ou=main,dc=example,dc=org
下组的角色映射映射到领域角色映射,而来自ou=finance,dc=example,dc=org
下组的角色映射映射到客户端finance
的客户端角色映射。 - 硬编码角色映射器
-
此映射器向来自 LDAP 提供程序的每个 Keycloak 用户授予指定的 Keycloak 角色。
- 组映射器
-
此映射器将 LDAP 树分支中的 LDAP 组映射到 Keycloak 中的组。此映射器还将用户组映射从 LDAP 传播到 Keycloak 中的用户组映射。
- MSAD 用户帐户映射器
-
此映射器特定于 Microsoft Active Directory (MSAD)。它可以将 MSAD 用户帐户状态集成到 Keycloak 帐户状态中,例如启用帐户或密码过期。此映射器使用
userAccountControl
和pwdLastSet
LDAP 属性,这些属性特定于 MSAD,而不是 LDAP 标准。例如,如果pwdLastSet
的值为0
,则 Keycloak 用户必须更新其密码。结果是向用户添加了 UPDATE_PASSWORD 必需操作。如果userAccountControl
的值为514
(禁用帐户),则 Keycloak 用户将被禁用。 - 证书映射器
-
此映射器映射 X.509 证书。Keycloak 将其与 X.509 身份验证和
PEM 格式的完整证书
作为身份源结合使用。此映射器的行为类似于用户属性映射器
,但 Keycloak 可以筛选存储 PEM 或 DER 格式证书的 LDAP 属性。使用此映射器启用始终从 LDAP 读取值
。
用户属性映射器将基本的 Keycloak 用户属性(例如用户名、名字、姓氏和电子邮件)映射到相应的 LDAP 属性。您可以扩展这些映射器并提供您自己的其他属性映射。管理员控制台提供工具提示以帮助配置相应的映射器。
密码哈希
当 Keycloak 更新密码时,Keycloak 以纯文本格式发送密码。此操作与在内置 Keycloak 数据库中更新密码不同,在内置 Keycloak 数据库中,Keycloak 会在将密码发送到数据库之前对其进行哈希和加盐处理。对于 LDAP,Keycloak 依赖 LDAP 服务器来哈希和加盐密码。
默认情况下,MSAD、RHDS 或 FreeIPA 等 LDAP 服务器会哈希和加盐密码。OpenLDAP 或 ApacheDS 等其他 LDAP 服务器以纯文本形式存储密码,除非您使用 RFC3062 中描述的LDAPv3 密码修改扩展操作。在 LDAP 配置页面中启用 LDAPv3 密码修改扩展操作。有关更多详细信息,请参阅您的 LDAP 服务器的文档。
始终通过使用 ldapsearch 检查已更改的目录条目并 base64 解码 userPassword 属性值,来验证用户密码是否已正确哈希并且未以纯文本形式存储。 |
配置连接池
为了在管理 LDAP 连接时提高效率,并在处理多个连接时提高性能,您可以启用连接池。通过这样做,当连接关闭时,它将被返回到池中以供将来使用,从而减少始终创建新连接的成本。
LDAP 连接池配置使用以下系统属性进行配置
名称 | 描述 |
---|---|
|
可以池化的连接的空格分隔的身份验证类型列表。有效类型为“none”、“simple”和“DIGEST-MD5” |
|
表示整数的字符串表示形式,该整数表示在最初为身份创建连接时,每个连接身份要创建的连接数 |
|
表示整数的字符串表示形式,该整数表示每个连接身份可以同时维护的最大连接数 |
|
表示整数的字符串表示形式,该整数表示每个连接身份应同时维护的首选连接数 |
|
表示整数的字符串表示形式,该整数表示空闲连接在池中可以保持多长时间(以毫秒为单位)而不会被关闭并从池中删除 |
|
可以池化的连接的空格分隔的协议类型列表。有效类型为“plain”和“ssl” |
|
指示要生成的调试输出级别的字符串。有效值为“fine”(跟踪连接创建和删除)和“all”(所有调试信息) |
默认情况下,为 plain
和 ssl
协议都启用了连接池。
有关更多详细信息,请参阅 Java LDAP 连接池配置 文档。
要设置任何这些属性,您可以设置 JAVA_OPTS_APPEND
环境变量
export JAVA_OPTS_APPEND=-Dcom.sun.jndi.ldap.connect.pool.initsize=10 -Dcom.sun.jndi.ldap.connect.pool.maxsize=50
故障排除
对于类别 org.keycloak.storage.ldap
,将日志记录级别提高到 TRACE 非常有用。通过此设置,许多日志消息将以 TRACE
级别发送到服务器日志,包括发送到 LDAP 服务器的所有查询以及用于发送查询的参数的日志记录。当您在用户论坛或 JIRA 上创建任何 LDAP 问题时,请考虑附加启用 TRACE 日志记录的服务器日志。如果日志太大,一个好的替代方法是仅包含来自服务器日志的代码片段,其中包含在导致您出现问题的操作期间添加到日志的消息。
-
当您创建 LDAP 提供程序时,服务器日志中会出现一条 INFO 级别的消息,以以下内容开头
Creating new LDAP Store for the LDAP storage provider: ...
它显示了您的 LDAP 提供程序的配置。在您提出问题或报告错误之前,最好包含此消息以显示您的 LDAP 配置。最终可以随意替换您不想包含的某些配置更改为某些占位符值。一个示例是 bindDn=some-placeholder
。对于 connectionUrl
,也可以随意替换它,但通常最好至少包含使用的协议(ldap
与 ldaps
)。同样,包含您的 LDAP 映射器配置的详细信息也很有用,这些详细信息在 DEBUG 级别以如下消息显示
Mapper for provider: XXX, Mapper name: YYY, Provider: ZZZ ...
请注意,这些消息仅在启用 DEBUG 日志记录时显示。
-
为了跟踪性能或连接池问题,请考虑将属性
com.sun.jndi.ldap.connect.pool.debug
的值设置为all
。此更改会在服务器日志中添加许多其他消息,其中包含 LDAP 连接池的日志记录。因此,您可以跟踪与连接池或性能相关的问题。有关更多详细信息,请参阅 配置连接池。
更改连接池的配置后,您可能需要重新启动 Keycloak 服务器以强制重新初始化 LDAP 提供程序连接。 |
即使在服务器重新启动后,如果仍然没有出现有关连接池的消息,则可能表明连接池不适用于您的 LDAP 服务器。
-
对于报告 LDAP 问题的情况,您可以考虑附加 LDAP 树的某些部分以及导致您环境中出现问题的目标数据。例如,如果某些用户的登录花费大量时间,您可以考虑附加他的 LDAP 条目,显示各种“组”条目的
member
属性的计数。在这种情况下,如果这些组条目映射到 Keycloak 中的某些组 LDAP 映射器(或角色 LDAP 映射器)等,则添加此信息可能很有用。
SSSD 和 FreeIPA 身份管理集成
Keycloak 包括 系统安全服务守护程序 (SSSD) 插件。SSSD 是 Fedora 和 Red Hat Enterprise Linux (RHEL) 的一部分,它提供对多个身份和身份验证提供程序的访问。SSSD 还提供诸如故障转移和离线支持等优势。有关更多信息,请参阅 Red Hat Enterprise Linux 身份管理文档。
SSSD 与 FreeIPA 身份管理 (IdM) 服务器集成,提供身份验证和访问控制。通过此集成,Keycloak 可以针对特权访问管理 (PAM) 服务进行身份验证,并从 SSSD 检索用户数据。有关在 Linux 环境中使用 Red Hat Identity Management 的更多信息,请参阅 Red Hat Enterprise Linux 身份管理文档。
Keycloak 和 SSSD 通过只读 D-Bus 接口进行通信。因此,配置和更新用户的方式是使用 FreeIPA/IdM 管理界面。默认情况下,该接口导入用户名、电子邮件、名字和姓氏。
Keycloak 自动注册组和角色,但不同步它们。组在首次访问用户时从 SSSD 导入,然后在 Keycloak 内部完全管理。管理员在 Keycloak 中进行的任何更改都不会与 SSSD 同步,反之亦然。 |
FreeIPA/IdM 服务器
FreeIPA 容器镜像 在 Quay.io 上可用。要设置 FreeIPA 服务器,请参阅 FreeIPA 文档。
-
使用以下命令运行您的 FreeIPA 服务器
docker run --name freeipa-server-container -it \ -h server.freeipa.local -e PASSWORD=YOUR_PASSWORD \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /var/lib/ipa-data:/data:Z freeipa/freeipa-server
带有
server.freeipa.local
的参数-h
表示 FreeIPA/IdM 服务器主机名。将YOUR_PASSWORD
更改为您自己的密码。 -
容器启动后,更改
/etc/hosts
文件以包含x.x.x.x server.freeipa.local
如果您不进行此更改,则必须设置 DNS 服务器。
-
使用以下命令将您的 Linux 服务器注册到 IPA 域中,以便 SSSD 联合提供程序在 Keycloak 上启动并运行
ipa-client-install --mkhomedir -p admin -w password
-
在客户端上运行以下命令以验证安装是否正常工作
kinit admin
-
输入您的密码。
-
使用以下命令将用户添加到 IPA 服务器
$ ipa user-add <username> --first=<first name> --last=<surname> --email=<email address> --phone=<telephoneNumber> --street=<street> --city=<city> --state=<state> --postalcode=<postal code> --password
-
使用 kinit 强制设置用户的密码。
kinit <username>
-
输入以下内容以恢复正常的 IPA 操作
kdestroy -A kinit admin
SSSD 和 D-Bus
联合提供程序使用 D-BUS 从 SSSD 获取数据。它使用 PAM 验证数据。
-
安装 sssd-dbus RPM。
$ sudo yum install sssd-dbus
-
运行以下配置脚本
$ bin/federation-sssd-setup.sh
该脚本也可以用作配置 SSSD 和 PAM 以用于 Keycloak 的指南。它对
/etc/sssd/sssd.conf
进行了以下更改[domain/your-hostname.local] ... ldap_user_extra_attrs = mail:mail, sn:sn, givenname:givenname, telephoneNumber:telephoneNumber ... [sssd] services = nss, sudo, pam, ssh, ifp ... [ifp] allowed_uids = root, yourOSUsername user_attributes = +mail, +telephoneNumber, +givenname, +sn
ifp
服务已添加到 SSSD,并配置为允许操作系统用户通过此接口查询 IPA 服务器。该脚本还创建了一个新的 PAM 服务
/etc/pam.d/keycloak
,以通过 SSSD 验证用户身份auth required pam_sss.so account required pam_sss.so
-
运行
dbus-send
以确保设置成功。dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe org.freedesktop.sssd.infopipe.GetUserAttr string:<username> array:string:mail,givenname,sn,telephoneNumber dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe org.freedesktop.sssd.infopipe.GetUserGroups string:<username>
如果设置成功,则每个命令分别显示用户的属性和组。如果出现超时或错误,则在 Keycloak 上运行的联合提供程序无法检索任何数据。此错误通常发生在服务器未注册到 FreeIPA IdM 服务器,或者没有访问 SSSD 服务的权限时。
如果您没有访问 SSSD 服务的权限,请确保运行 Keycloak 服务器的用户在
/etc/sssd/sssd.conf
文件中的以下部分中[ifp] allowed_uids = root, yourOSUsername
并且在主机内部创建了
ipaapi
系统用户。此用户对于ifp
服务是必需的。检查用户是否在系统中创建。grep ipaapi /etc/passwd ipaapi:x:992:988:IPA Framework User:/:/sbin/nologin
自定义提供程序
Keycloak 确实有一个用户存储联合服务提供商接口 (SPI),用于开发自定义提供程序。您可以在服务器开发人员指南中找到有关开发客户提供程序的文档。
管理用户
在管理控制台中,您可以执行各种操作来管理用户。
创建用户
您在您打算拥有这些用户所需应用程序的 realm 中创建用户。 避免在 master realm 中创建用户,master realm 仅用于创建其他 realm。
-
您位于 master realm 以外的 realm 中。
-
在菜单中点击用户。
-
点击添加用户。
-
输入新用户的详细信息。
用户名是唯一必填字段。 -
点击保存。 保存详细信息后,将显示新用户的管理页面。
管理用户属性
在 Keycloak 中,用户与一组属性相关联。 这些属性用于更好地描述和识别 Keycloak 中的用户,以及将有关他们的附加信息传递给应用程序。
用户配置文件定义了一个明确的模式,用于表示用户属性以及它们在 realm 中的管理方式。 通过提供用户信息的一致视图,它允许管理员控制属性管理方式的不同方面,并使扩展 Keycloak 以支持其他属性变得更加容易。
虽然用户配置文件主要针对最终用户可以管理的属性(例如:名字和姓氏、电话等),但它也用于管理您想要与用户关联的任何其他元数据。
除了其他功能外,用户配置文件还使管理员能够
-
定义用户属性的模式
-
根据上下文信息定义属性是否为必需(例如:如果仅对用户、管理员或两者都必需,或者取决于所请求的范围。)
-
定义查看和编辑用户属性的特定权限,从而可以遵守严格的隐私要求,其中某些属性不能被第三方(包括管理员)查看或更改
-
动态强制执行用户配置文件合规性,以便用户信息始终更新并符合与属性关联的元数据和规则
-
通过利用内置验证器或编写自定义验证器,在每个属性的基础上定义验证规则
-
根据属性定义,动态呈现用户在帐户控制台中与之交互的表单,例如注册、更新个人资料、代理和个人信息,而无需手动更改主题。
-
自定义管理控制台中的用户管理界面,以便根据用户配置文件模式动态呈现属性
用户配置文件模式或配置使用 JSON 格式来表示属性及其元数据。 在管理控制台中,您可以通过点击左侧菜单中的Realm 设置
,然后点击该页面上的用户配置文件
选项卡来管理配置。
在接下来的章节中,我们将了解如何创建您自己的用户配置文件模式或配置,以及如何管理属性。
了解默认配置
默认情况下,Keycloak 提供了一个基本的用户配置文件配置,涵盖了一些最常见的用户属性
名称 | 描述 |
---|---|
|
用户名 |
|
最终用户的首选电子邮件地址。 |
|
最终用户的给定名称或名字 |
|
最终用户的姓氏 |
在 Keycloak 中,“用户名”和“电子邮件”属性都经过特殊处理,因为它们通常用于识别、验证和链接用户帐户。 对于这些属性,您只能更改其设置,而不能删除它们。
“用户名”和“电子邮件”属性的行为会根据您 realm 的“登录”设置而变化。 例如,更改“将电子邮件作为用户名”或“编辑用户名”设置将覆盖您在用户配置文件配置中设置的任何配置。 |
正如您将在以下章节中看到的那样,您可以自由更改默认配置,方法是引入您自己的属性或更改任何可用属性的设置,以更好地满足您的需求。
了解用户配置文件上下文
在 Keycloak 中,用户通过不同的上下文进行管理
-
注册
-
更新个人资料
-
通过代理或社交提供商进行身份验证时审查个人资料
-
帐户控制台
-
管理(例如:管理控制台和 Admin REST API)
除了“管理”上下文之外,所有其他上下文都被视为最终用户上下文,因为它们与用户自助服务流程相关。
了解这些上下文对于理解在管理用户时用户配置文件配置将在何处生效非常重要。 无论用户在哪个上下文中被管理,都将使用相同的用户配置文件配置来呈现 UI 并验证属性值。
正如您将在以下章节中看到的那样,您可能会限制某些属性仅在管理上下文中可用,并为最终用户完全禁用它们。 反之亦然,如果您不希望管理员访问某些用户属性,而只允许最终用户访问。
了解托管和非托管属性
默认情况下,Keycloak 只会识别在您的用户配置文件配置中定义的属性。 服务器会忽略任何其他未在此处明确定义的属性。
通过严格控制可以为用户设置哪些用户属性以及如何验证其值,Keycloak 可以为您的 realm 添加另一道防御屏障,并帮助您防止与用户关联的意外属性和值。
也就是说,用户属性可以按如下方式分类
-
托管。 这些是受您的用户配置文件控制的属性,您希望允许最终用户和管理员从任何用户配置文件上下文中管理它们。 对于这些属性,您希望完全控制它们的管理方式和时间。
-
非托管。 这些是您未在用户配置文件中明确定义的属性,因此默认情况下 Keycloak 会完全忽略它们。
虽然默认情况下禁用非托管属性,但您可以使用不同的策略配置您的 realm,以定义服务器如何处理它们。 为此,请点击左侧菜单中的Realm 设置
,点击常规
选项卡,然后从非托管属性
设置中选择以下任何选项
-
已禁用。 这是默认策略,因此非托管属性在所有用户配置文件上下文中都被禁用。
-
已启用。 此策略在所有用户配置文件上下文中启用非托管属性。
-
管理员可以查看。 此策略仅在管理上下文中以只读方式启用非托管属性。
-
管理员可以编辑。 此策略仅在管理上下文中启用非托管属性以进行读取和写入。
这些策略使您可以精细地控制服务器将如何处理非托管属性。 您可以选择完全禁用,或者仅在通过管理上下文管理用户时支持非托管属性。
当启用非托管属性(即使是部分启用)时,您可以从管理控制台中的“用户详细信息”UI 的“属性”选项卡管理它们。 如果策略设置为“已禁用”,则此选项卡不可用。
作为安全建议,请尽量遵守最严格的策略(例如:“已禁用”或“管理员可以编辑”),以防止当用户通过最终用户上下文管理其个人资料时,为您的用户设置意外属性(和值)。 避免设置“已启用”策略,并优先在您的用户配置文件配置中定义最终用户可以管理的所有属性,并在您的控制之下。
“已启用”策略的目标是 realm 从以前版本的 Keycloak 迁移,并避免在使用自定义主题和使用他们自己的自定义用户属性扩展服务器时破坏行为。 |
正如您将在以下章节中看到的那样,您还可以通过选择属性是否应用户和/或管理员可见或可写来限制属性的受众。
对于非托管属性,最大长度为 2048 个字符。 要指定不同的最小或最大长度,请将非托管属性更改为托管属性并添加长度验证器。
Keycloak 在其内部缓存中缓存用户相关对象。 属性越长,缓存消耗的内存就越多。 因此,建议限制长度属性的大小。 考虑在 Keycloak 外部存储大型对象,并通过 ID 或 URL 引用它们。 |
管理用户配置文件
用户配置文件配置是在每个 realm 的基础上进行管理的。 为此,请点击左侧菜单中的Realm 设置
链接,然后点击用户配置文件
选项卡。
在属性
子选项卡中,您可以看到所有托管属性的列表。
在属性组
子选项卡中,您可以管理属性组。 属性组允许您关联属性,以便在呈现面向用户的表单时将它们一起显示。
在JSON 编辑器
子选项卡中,您可以查看和编辑 JSON 配置。 您可以使用此选项卡来获取当前配置或手动管理它。 您在此选项卡上所做的任何更改都会反映在其他选项卡中,反之亦然。
在下一节中,您将学习如何管理属性。
管理属性
在属性
子选项卡中,您可以创建、编辑和删除托管属性。
要定义新属性并将其与用户配置文件关联,请点击属性列表顶部的创建属性按钮。
配置属性时,您可以定义以下设置
- 名称
-
属性的名称,用于唯一标识属性。
- 显示名称
-
属性的用户友好名称,主要在呈现面向用户的表单时使用。 它还支持使用国际化消息
- 多值
-
如果启用,则属性支持多个值,并且 UI 会相应呈现以允许设置多个值。 启用此设置时,请确保添加验证器以设置值的硬性限制。
- 属性组
-
属性所属的属性组(如果有)。
- 启用条件
-
启用或禁用属性。 如果设置为
始终
,则该属性在任何用户配置文件上下文中都可用。 如果设置为请求作用域
,则仅当代表用户的客户端请求一组或多个作用域时,该属性才可用。 您可以使用此选项根据请求的客户端作用域动态强制执行某些属性。 对于管理控制台,不评估作用域,并且始终启用该属性。 这是因为按作用域过滤属性仅在运行最终用户身份验证流程时才有效。 - 必需
-
设置将属性标记为必填的条件。如果禁用,则该属性是可选的。如果启用,您可以设置
Required for
设置,以根据用户配置文件上下文将属性标记为必填,以便该属性对于最终用户(通过最终用户上下文)或管理员(通过管理上下文)或两者都是必填的。您还可以设置Required when
设置,以仅当请求了一组或多个客户端范围时才将属性标记为必填。如果设置为Always
,则该属性在任何用户配置文件上下文中都是必填的。如果设置为Scopes are requested
,则仅当代表用户操作的客户端请求一组或多个范围时,该属性才是必填的。对于帐户和管理控制台,不评估范围,并且该属性不是必填的。这是因为按范围过滤属性仅在运行身份验证流程时才有效。 - 权限
-
在本节中,您可以定义从最终用户或管理上下文中管理属性时的读取和写入权限。
Who can edit
设置将属性标记为可由User
和/或Admin
从最终用户和管理上下文中分别写入。Who can view
设置将属性标记为可由User
和/或Admin
从最终用户和管理上下文中分别读取。 - 验证
-
在本节中,您可以定义在管理属性值时将执行的验证。Keycloak 提供了一组内置的验证器,您可以从中选择,并且可以添加您自己的验证器。有关更多详细信息,请参阅 验证属性 部分。
- 注解
-
在本节中,您可以将注解与属性关联。注解主要用于将额外的元数据传递到前端以进行渲染。有关更多详细信息,请参阅 定义 UI 注解 部分。
当您创建属性时,该属性仅在管理上下文中可用,以避免意外地向最终用户公开属性。实际上,当最终用户通过最终用户上下文管理他们的个人资料时,该属性将无法被最终用户访问。您可以随时根据您的需要更改 Permissions
设置。
验证属性
您可以启用对受管理属性的验证,以确保属性值符合特定规则。为此,您可以在管理属性时从 Validations
设置中添加或删除验证器。
验证发生在任何写入属性的时候,并且它们可能会抛出错误,当值未能通过验证时,这些错误将显示在 UI 中。
出于安全原因,每个可由用户编辑的属性都应该进行验证,以限制用户输入的值的大小。如果未指定 length
验证器,Keycloak 默认最大长度为 2048 个字符。
内置验证器
Keycloak 提供了一些内置的验证器供您选择,您也可以通过扩展 Validator SPI
来提供您自己的验证器。
以下列表提供了所有内置验证器的列表
名称 | 描述 | 配置 |
---|---|---|
length |
检查字符串值的长度,基于最小和最大长度。 |
min:一个整数,用于定义允许的最小长度。 max:一个整数,用于定义允许的最大长度。 trim-disabled:一个布尔值,用于定义在验证之前是否修剪值。 |
integer |
检查值是否为整数,并在下限和/或上限范围内。如果未定义范围,则验证器仅检查值是否为有效数字。 |
min:一个整数,用于定义下限范围。 max:一个整数,用于定义上限范围。 |
double |
检查值是否为双精度浮点数,并在下限和/或上限范围内。如果未定义范围,则验证器仅检查值是否为有效数字。 |
min:一个整数,用于定义下限范围。 max:一个整数,用于定义上限范围。 |
uri |
检查值是否为有效的 URI。 |
None |
pattern |
检查值是否与特定的 RegEx 模式匹配。 |
pattern:用于验证值的 RegEx 模式。 error-message:i18n 捆绑包中错误消息的键。如果未设置,则使用通用消息。 |
检查值是否具有有效的电子邮件格式。 |
max-local-length:一个整数,用于定义电子邮件本地部分的最大长度。根据规范,默认为 64。 |
|
local-date |
检查值是否具有基于领域和/或用户区域设置的有效格式。 |
None |
iso-date |
检查值是否具有基于 ISO 8601 的有效格式。此验证器可以与使用 html5-date 输入类型的输入一起使用。 |
None |
person-name-prohibited-characters |
检查值是否为有效的人员姓名,作为防止脚本注入等攻击的额外屏障。验证基于默认的 RegEx 模式,该模式阻止人员姓名中不常见的字符。 |
error-message:i18n 捆绑包中错误消息的键。如果未设置,则使用通用消息。 |
username-prohibited-characters |
检查值是否为有效的用户名,作为防止脚本注入等攻击的额外屏障。验证基于默认的 RegEx 模式,该模式阻止用户名中不常见的字符。当领域设置 |
error-message:i18n 捆绑包中错误消息的键。如果未设置,则使用通用消息。 |
options |
检查值是否来自定义的允许值集合。用于验证通过选择和多选字段输入的值非常有用。 |
options:包含允许值的字符串数组。 |
up-username-not-idn-homograph |
该字段只能包含拉丁字符和常见的 Unicode 字符。对于可能遭受 IDN 同形字攻击的字段(通常是用户名)很有用。 |
error-message:i18n 捆绑包中错误消息的键。如果未设置,则使用通用消息。 |
multivalued |
验证多值属性的大小。 |
min:一个整数,用于定义允许的最小属性值计数。 max:一个整数,用于定义允许的最大属性值计数。 |
定义 UI 注解
为了将额外的信息传递给前端,可以使用注解来装饰属性,以指示如何渲染属性。当扩展 Keycloak 主题以基于与属性关联的注解动态渲染页面时,此功能主要有用。
注解用于例如 更改属性的 HTML type
和 更改属性的 DOM 表示形式,正如您将在以下部分中看到的那样。
注解是与 UI 共享的键/值对,以便它们可以更改与属性对应的 HTML 元素的渲染方式。您可以为属性设置任何您想要的注解,只要注解受您的领域正在使用的主题支持。
您唯一的限制是避免在其键中使用 |
内置注解
以下注解受 Keycloak 内置主题支持
名称 | 描述 |
---|---|
inputType |
表单输入字段的类型。可用类型在下表中描述。 |
inputHelperTextBefore |
在输入字段之前(上方)渲染的辅助文本。此处可以使用直接文本或国际化模式(如 |
inputHelperTextAfter |
在输入字段之后(下方)渲染的辅助文本。此处可以使用直接文本或国际化模式(如 |
inputOptionsFromValidation |
用于选择和多选类型的注解。用于从自定义属性验证中获取输入选项的可选名称。请参阅下方的 详细描述。 |
inputOptionLabelsI18nPrefix |
用于选择和多选类型的注解。用于在 UI 中渲染选项的国际化键前缀。请参阅下方的 详细描述。 |
inputOptionLabels |
用于选择和多选类型的注解。用于定义选项的 UI 标签的可选映射(直接或使用国际化)。请参阅下方的 详细描述。 |
inputTypePlaceholder |
应用于字段的 HTML 输入 |
inputTypeSize |
应用于字段的 HTML 输入 |
inputTypeCols |
应用于字段的 HTML 输入 |
inputTypeRows |
应用于字段的 HTML 输入 |
inputTypePattern |
应用于字段的 HTML 输入 |
inputTypeMaxLength |
应用于字段的 HTML 输入 |
inputTypeMinLength |
应用于字段的 HTML 输入 |
inputTypeMax |
应用于字段的 HTML 输入 |
inputTypeMin |
应用于字段的 HTML 输入 |
inputTypeStep |
应用于字段的 HTML 输入 |
数字格式 |
如果设置, |
数字取消格式化 |
如果设置, |
字段类型使用 HTML 表单字段标签和应用于它们的属性 - 它们的行为基于 HTML 规范和浏览器对它们的支持。 视觉渲染也取决于所用主题中应用的 CSS 样式。 |
更改属性的 HTML type
您可以通过设置 inputType
注解来更改 HTML5 输入元素的 type
。可用类型包括
名称 | 描述 | 使用的 HTML 标签 |
---|---|---|
text |
单行文本输入。 |
input |
textarea |
多行文本输入。 |
textarea |
select |
常见的单选输入。请参阅下方的 描述如何配置选项。 |
select |
select-radiobuttons |
通过单选按钮组的单选输入。请参阅下方的 描述如何配置选项。 |
输入组 |
multiselect |
常见的多选输入。请参阅下方的 描述如何配置选项。 |
select |
multiselect-checkboxes |
通过复选框组的多选输入。请参阅下方的 描述如何配置选项。 |
输入组 |
html5-email |
基于 HTML 5 规范的电子邮件地址的单行文本输入。 |
input |
html5-tel |
基于 HTML 5 规范的电话号码的单行文本输入。 |
input |
html5-url |
基于 HTML 5 规范的 URL 的单行文本输入。 |
input |
html5-number |
基于 HTML 5 规范的数字(整数或浮点数,取决于 |
input |
html5-range |
基于 HTML 5 规范的用于输入数字的滑块。 |
input |
html5-datetime-local |
基于 HTML 5 规范的日期时间输入。 |
input |
html5-date |
基于 HTML 5 规范的日期输入。 |
input |
html5-month |
基于 HTML 5 规范的月份输入。 |
input |
html5-week |
基于 HTML 5 规范的星期输入。 |
input |
html5-time |
基于 HTML 5 规范的时间输入。 |
input |
定义选择和多选字段的选项
选择和多选字段的选项取自应用于属性的验证,以确保 UI 中呈现的验证和字段选项始终一致。默认情况下,选项取自内置的 options
验证。
您可以使用多种方法为选择和多选选项提供良好的人类可读标签。最简单的情况是属性值与 UI 标签相同。在这种情况下,无需额外的配置。
当属性值是某种不适用于 UI 的 ID 时,您可以使用 inputOptionLabelsI18nPrefix
注解提供的简单国际化支持。它定义了国际化键的前缀,选项值是附加到此前缀的点。
选项值的本地化 UI 标签文本必须通过 userprofile.jobtitle.sweng
和 userprofile.jobtitle.swarch
键提供,然后使用通用的本地化机制。
您还可以使用 inputOptionLabels
注解为各个选项提供标签。它包含一个选项标签的映射 - 映射中的键是选项值(在验证中定义),映射中的值是 UI 标签文本本身或该选项的国际化模式(例如 ${i18n.key}
)。
您必须使用用户配置文件的 |
直接输入的各个选项标签示例(不使用国际化)
"attributes": [
<...
{
"name": "jobTitle",
"validations": {
"options": {
"options":[
"sweng",
"swarch"
]
}
},
"annotations": {
"inputType": "select",
"inputOptionLabels": {
"sweng": "Software Engineer",
"swarch": "Software Architect"
}
}
}
...
]
国际化的各个选项标签示例
"attributes": [
...
{
"name": "jobTitle",
"validations": {
"options": {
"options":[
"sweng",
"swarch"
]
}
},
"annotations": {
"inputType": "select-radiobuttons",
"inputOptionLabels": {
"sweng": "${jobtitle.swengineer}",
"swarch": "${jobtitle.swarchitect}"
}
}
}
...
]
本地化文本必须通过 jobtitle.swengineer
和 jobtitle.swarchitect
键提供,然后使用通用的本地化机制。
借助 inputOptionsFromValidation
属性注解,可以使用自定义验证器来提供选项。此验证必须具有提供选项数组的 options
配置。国际化的工作方式与内置 options
验证提供的选项相同。
更改属性的 DOM 表示形式
您可以通过设置带有 kc
前缀的注解来启用额外的客户端行为。这些注解将转换为属性的相应元素中的 HTML 属性,并以 data-
为前缀。具有相同名称的脚本将被加载到动态页面,以便您可以根据自定义的 data-
属性从 DOM 中选择元素,并通过修改其 DOM 表示形式来相应地装饰它们。
例如,如果您向属性添加 kcMyCustomValidation
注解,则 HTML 属性 data-kcMyCustomValidation
将添加到属性的相应 HTML 元素中,并且 JavaScript 模块将从您的自定义主题中的 <THEME TYPE>/resources/js/kcMyCustomValidation.js
加载。有关如何将自定义 JavaScript 模块部署到主题的更多信息,请参阅 服务器开发人员指南。
JavaScript 模块可以运行任何代码来自定义 DOM 和为每个属性呈现的元素。为此,您可以使用 userProfile.js
模块为您的自定义注解注册注解描述符,如下所示
import { registerElementAnnotatedBy } from "./userProfile.js";
registerElementAnnotatedBy({
name: 'kcMyCustomValidation',
onAdd(element) {
var listener = function (event) {
// do something on keyup
};
element.addEventListener("keyup", listener);
// returns a cleanup function to remove the event listener
return () => element.removeEventListener("keyup", listener);
}
});
registerElementAnnotatedBy
是一种注册注解描述符的方法。描述符是一个对象,其中包含 name
(引用注解名称)和一个 onAdd
函数。每当页面呈现或将带有注解的属性添加到 DOM 时,都会调用 onAdd
函数,以便您可以自定义元素的行为。
onAdd
函数还可以返回一个函数来执行清理操作。例如,如果您正在向元素添加事件侦听器,您可能希望在元素从 DOM 中移除时移除它们。
或者,如果 userProfile.js
不足以满足您的需求,您也可以使用任何您想要的 JavaScript 代码
document.querySelectorAll(`[data-kcMyCustomValidation]`).forEach((element) => {
var listener = function (evt) {
// do something on keyup
};
element.addEventListener("keyup", listener);
});
管理属性组
在 属性组
子选项卡中,您可以创建、编辑和删除属性组。属性组允许您为相关的属性定义一个容器,以便它们在面向用户的表单中一起呈现。
您无法删除绑定到属性的属性组。为此,您应该首先更新属性以删除绑定。 |
要创建新组,请单击属性组列表顶部的 创建属性组 按钮。
配置组时,您可以定义以下设置
使用 JSON 配置
用户配置文件配置使用明确定义的 JSON 模式存储。您可以选择通过单击 JSON 编辑器
子选项卡直接编辑用户配置文件配置。
JSON 模式定义如下
{
"unmanagedAttributePolicy": "DISABLED",
"attributes": [
{
"name": "myattribute",
"multivalued": false,
"displayName": "My Attribute",
"group": "personalInfo",
"required": {
"roles": [ "user", "admin" ],
"scopes": [ "foo", "bar" ]
},
"permissions": {
"view": [ "admin", "user" ],
"edit": [ "admin", "user" ]
},
"validations": {
"email": {
"max-local-length": 64
},
"length": {
"max": 255
}
},
"annotations": {
"myannotation": "myannotation-value"
}
}
],
"groups": [
{
"name": "personalInfo",
"displayHeader": "Personal Information",
"annotations": {
"foo": ["foo-value"],
"bar": ["bar-value"]
}
}
]
}
该模式支持您需要的任意数量的属性和组。
unmanagedAttributePolicy
属性通过设置以下值之一来定义非托管属性策略。有关更多详细信息,请查看 了解托管和非托管属性。
-
禁用
-
启用
-
管理员视图
-
管理员编辑
属性模式
对于每个属性,您应该定义一个 name
,以及可选的 required
、permission
和 annotations
设置。
required
属性定义属性是否为必需。Keycloak 允许您根据不同的条件将属性设置为必需。
当 required
属性定义为空对象时,该属性始终为必需。
{
"attributes": [
{
"name": "myattribute",
"required": {}
]
}
另一方面,您可以选择仅对用户、管理员或两者都要求该属性为必需。以及仅在用户在 Keycloak 中进行身份验证时请求特定范围的情况下,将属性标记为必需。
要将属性标记为用户和/或管理员必需,请按如下所示设置 roles
属性
{
"attributes": [
{
"name": "myattribute",
"required": {
"roles": ["user"]
}
]
}
roles
属性需要一个数组,其值可以是 user
或 admin
,具体取决于属性是用户还是管理员必需的。
同样,您可以选择在客户端在验证用户身份时请求一组或多个范围时,使属性成为必需。为此,您可以使用 scopes
属性,如下所示
{
"attributes": [
{
"name": "myattribute",
"required": {
"scopes": ["foo"]
}
]
}
scopes
属性是一个数组,其值可以是表示客户端范围的任何字符串。
属性级别的 permissions
属性可用于定义属性的读取和写入权限。权限的设置基于用户、管理员或两者是否可以对属性执行这些操作。
{
"attributes": [
{
"name": "myattribute",
"permissions": {
"view": ["admin"],
"edit": ["user"]
}
]
}
view
和 edit
属性都期望一个数组,其值可以是 user
或 admin
,具体取决于属性是否可由用户或管理员查看或编辑。
当授予 edit
权限时,将隐式授予 view
权限。
属性级别的 annotation
属性可用于将额外的元数据关联到属性。注解主要用于将有关属性的附加信息传递到前端,以便根据用户配置文件配置呈现用户属性。每个注解都是键/值对。
{
"attributes": [
{
"name": "myattribute",
"annotations": {
"foo": ["foo-value"],
"bar": ["bar-value"]
}
]
}
自定义 UI 的呈现方式
来自所有用户配置文件上下文(包括管理控制台)的 UI 都会根据您的用户配置文件配置动态呈现。
默认呈现机制提供以下功能
-
根据为属性设置的权限显示或隐藏字段。
-
根据为属性设置的约束,为必填字段呈现标记。
-
更改设置为属性的字段输入类型(文本、日期、数字、选择、多选)。
-
根据为属性设置的权限将字段标记为只读。
-
根据为属性设置的顺序对字段进行排序。
-
对属于同一属性组的字段进行分组。
-
动态地对属于同一属性组的字段进行分组。
启用渐进式配置
为了确保最终用户配置文件符合配置,管理员可以使用 VerifyProfile
必需操作,以最终强制用户在向 Keycloak 验证身份时更新其配置文件。
|
启用后,当用户进行身份验证时,VerifyProfile
操作将执行以下步骤
-
检查用户配置文件是否完全符合为 realm 设置的用户配置文件配置。这意味着运行验证并确保所有验证都成功。
-
如果不符合,则在身份验证期间执行一个额外的步骤,以便用户可以更新任何缺失或无效的属性。
-
如果用户配置文件符合配置,则不执行任何额外的步骤,用户继续进行身份验证过程。
VerifyProfile
操作默认启用。要禁用它,请单击左侧菜单上的 身份验证
链接,然后单击 必需操作
选项卡。在此选项卡中,使用 VerifyProfile
操作的 已启用 开关来禁用它。
使用国际化消息
如果您想在配置属性、属性组和注解时使用国际化消息,您可以使用占位符设置它们的显示名称、描述和值,该占位符将转换为消息包中的消息。
为此,您可以使用占位符来解析消息键,例如 ${myAttributeName}
,其中 myAttributeName
是消息包中消息的键。有关如何将消息包添加到自定义主题的更多详细信息,请参阅 服务器开发人员指南。
定义用户凭据
您可以在 凭据 选项卡中管理用户的凭据。
您可以通过拖放行来更改凭据的优先级。新顺序决定了该用户凭据的优先级。最顶部的凭据具有最高的优先级。优先级决定了用户登录后首先显示哪个凭据。
- 类型
-
此列显示凭据的类型,例如 密码 或 OTP。
- 用户标签
-
这是一个可分配的标签,用于在登录期间作为选择选项呈现凭据时识别凭据。它可以设置为任何值来描述凭据。
- 数据
-
这是关于凭据的非机密技术信息。默认情况下它是隐藏的。您可以单击 显示数据… 以显示凭据的数据。
- 操作
-
单击 重置密码 以更改用户的密码,单击 删除 以删除凭据。
您无法在管理控制台中为特定用户配置其他类型的凭据;这项任务是用户的责任。
如果用户丢失了 OTP 设备或凭据已泄露,您可以删除用户的凭据。您只能在 凭据 选项卡中删除用户的凭据。
为用户设置密码
如果用户没有密码,或者密码已被删除,则会显示 设置密码 部分。
如果用户已经有密码,则可以在 重置密码 部分重置密码。
-
在菜单中单击 用户。将显示 用户 页面。
-
选择一个用户。
-
单击 凭据 选项卡。
-
在 设置密码 部分中键入新密码。
-
单击 设置密码。
如果 临时 为 开启,则用户必须在首次登录时更改密码。要允许用户保留提供的密码,请将 临时 设置为 关闭。用户必须单击 设置密码 才能更改密码。
允许用户自助注册
您可以将 Keycloak 用作第三方授权服务器来管理应用程序用户,包括自助注册的用户。如果您启用自助注册,登录页面将显示注册链接,以便用户可以创建帐户。
用户必须在注册表单中添加个人资料信息才能完成注册。注册表单可以通过删除或添加用户必须填写的字段进行自定义。
即使禁用自助注册,仍然可以通过以下任一方式将新用户添加到 Keycloak:
-
管理员可以使用管理控制台(或管理 REST API)添加新用户
-
当启用身份代理时,通过身份提供商验证的新用户可能会自动添加/注册到 Keycloak 存储中。有关更多信息,请参阅身份代理章节中的首次登录流程部分。
此外,来自第三方用户存储(例如 LDAP)的用户在启用特定用户存储时会自动在 Keycloak 中可用
-
有关自定义用户注册的更多信息,请参阅服务器开发人员指南。
定义登录时需要的操作
您可以设置用户在首次登录时必须执行的操作。这些操作在用户提供凭据后是必需的。首次登录后,这些操作不再是必需的。您可以在该用户的 Details(详情) 选项卡上添加必需的操作。
即使管理员没有显式地将某些必需的操作添加到用户,这些操作也会在用户登录期间自动触发。例如,如果密码策略配置为用户密码需要每 X 天更改一次,则可以触发 Update password(更新密码)
操作。或者,如果某些用户属性不符合用户配置文件配置的要求,verify profile(验证个人资料)
操作可能会要求用户更新用户配置文件。
以下是必需的操作类型的示例
- 更新密码
-
用户必须更改其密码。
- 配置 OTP
-
用户必须使用 Free OTP 或 Google Authenticator 应用程序在其移动设备上配置一次性密码生成器。
- 验证电子邮件
-
用户必须验证其电子邮件帐户。将向用户发送一封包含验证链接的电子邮件,用户必须点击该链接。成功完成此工作流程后,用户将被允许登录。
- 更新个人资料
-
用户必须更新个人资料信息,例如姓名、地址、电子邮件和电话号码。
某些操作直接添加到用户帐户是没有意义的。例如,Update User Locale(更新用户区域设置) 是一个辅助操作,用于处理一些本地化相关参数。另一个例子是 Delete Credential(删除凭据) 操作,它应该作为参数化 AIA 触发。关于这一点,如果管理员想要删除某些用户的凭据,管理员可以直接在管理控制台中执行此操作。Delete Credential(删除凭据) 操作专门用于例如Keycloak 帐户控制台。 |
为一个用户设置必需的操作
您可以设置任何用户都需要的操作。
-
在菜单中点击用户。
-
从列表中选择一个用户。
-
导航到 Required User Actions(必需的用户操作) 列表。
-
选择要添加到帐户的所有操作。
-
点击操作名称旁边的 X 以移除它。
-
在选择要添加的操作后,点击 保存。
为所有用户设置必需的操作
您可以指定所有新用户首次登录之前需要执行哪些操作。这些要求适用于通过 Users(用户) 页面上的 Add User(添加用户) 按钮或登录页面上的 Register(注册) 链接创建的用户。
-
点击菜单中的 身份验证。
-
点击 Required Actions(必需的操作) 选项卡。
-
为一个或多个必需的操作点击 Set as default action(设置为默认操作) 列中的复选框。当新用户首次登录时,必须执行所选的操作。
启用条款和条件作为必需的操作
您可以启用一个必需的操作,即新用户必须接受条款和条件才能首次登录 Keycloak。
-
点击菜单中的 身份验证。
-
点击 Required Actions(必需的操作) 选项卡。
-
启用 条款和条件 操作。
-
编辑基本登录主题中的
terms.ftl
文件。
-
有关扩展和创建主题的更多信息,请参阅服务器开发人员指南。
应用程序发起的动作
应用程序发起的动作 (AIA) 允许客户端应用程序请求用户在 Keycloak 端执行操作。通常,当 OIDC 客户端应用程序希望用户登录时,它会将用户重定向到登录 URL,如OIDC 章节中所述。登录后,用户将被重定向回客户端应用程序。用户执行管理员要求的操作,如上一节中所述,然后立即重定向回应用程序。但是,AIA 允许客户端应用程序在登录期间请求用户执行某些必需的操作。即使用户已在客户端上通过身份验证并且具有活动的 SSO 会话,也可以执行此操作。它通过将 kc_action
参数添加到 OIDC 登录 URL,其值包含请求的操作来触发。例如 kc_action=UPDATE_PASSWORD
参数。
用户可以取消应用程序发起的动作。在这种情况下,用户将被重定向回客户端应用程序。重定向 URI 将包含查询参数 kc_action_status=cancelled
和 kc_action
以及已取消操作的名称。
kc_action 和 kc_action_status 参数是 Keycloak 专有的机制,OIDC 规范不支持。 |
应用程序发起的动作仅支持 OIDC 客户端。 |
因此,如果使用 AIA,示例流程类似于以下内容
-
客户端应用程序将用户重定向到 OIDC 登录 URL,并带有附加参数,例如
kc_action=UPDATE_PASSWORD
-
始终会触发身份验证流程部分中描述的
browser
流程。如果用户未通过身份验证,则该用户需要像正常登录期间一样进行身份验证。如果用户已经过身份验证,则可以通过 SSO cookie 自动重新身份验证,而无需主动重新身份验证并再次提供凭据。在这种情况下,该用户将直接重定向到具有特定操作的屏幕(在本例中为更新密码)。但是,在某些情况下,即使用户具有 SSO cookie,也需要主动重新身份验证(有关详细信息,请参阅下文)。 -
具有特定操作(在本例中为
update password
)的屏幕将显示给用户,以便用户需要执行特定操作 -
然后用户被重定向回客户端应用程序
请注意,Keycloak 帐户控制台 使用 AIA 来请求更新密码或重置其他凭据,例如 OTP 或 WebAuthn。
即使使用了参数 kc_action ,也不能认为用户总是执行该操作。例如,用户可能已手动从浏览器 URL 中删除了 kc_action 参数。因此,无法保证在客户端请求 kc_action=CONFIGURE_TOTP 后,用户帐户具有 OTP。如果您想验证用户是否配置了双因素身份验证器,则客户端应用程序可能需要检查它是否已配置。例如,通过检查令牌中的 acr 等声明。 |
AIA 期间的重新身份验证
如果用户由于活动的 SSO 会话而已通过身份验证,则该用户通常不需要主动重新身份验证。但是,如果该用户主动身份验证的时间超过五分钟前,则当请求某些 AIA 时,客户端仍然可以请求重新身份验证。以下是此指南的例外情况:
-
delete_account
操作将始终要求用户主动重新身份验证 -
UPDATE_PASSWORD
操作可能需要用户根据配置的最大身份验证年龄密码策略主动重新身份验证。如果未配置策略,也可以在配置特定必需操作时在必需的操作选项卡上配置策略。如果未在任何这些位置配置策略,则默认为五分钟。 -
如果您想使用更短的重新身份验证,您仍然可以使用参数查询参数,例如
max_age
与指定的更短值,或者最终使用prompt=login
,这将始终要求用户主动重新身份验证,如 OIDC 规范中所述。请注意,不支持对max_age
使用长于默认五分钟(或密码策略规定的值)的值。max_age
目前只能用于使该值短于默认的五分钟。 -
如果启用了增强身份验证,且操作是添加或删除凭据,则需要使用与给定凭据级别对应的级别进行身份验证。如果用户已拥有特定级别的凭据,则存在此要求。例如,如果在身份验证流程中配置了
otp
和webauthn
作为第二因素身份验证器(都在级别 2 的身份验证流程中),并且用户已拥有第二因素凭据(在本例中为otp
或webauthn
),则用户需要使用现有的第二因素凭据进行身份验证,才能添加另一个第二级凭据。同样,删除现有的第二因素凭据(在本例中为otp
或webauthn
)时,也需要使用现有的第二因素级别凭据进行身份验证。存在此要求是出于安全原因。
参数化 AIA
一些 AIA 可能需要与操作名称一起发送参数。例如,只有 AIA 才能触发 删除凭据
操作,并且它需要与操作名称一起发送参数,该参数指向要删除的凭据的 ID。因此,此示例的 URL 将是 kc_action=delete_credential:ce1008ac-f811-427f-825a-c0b878d1c24b
。在这种情况下,冒号字符 (ce1008ac-f811-427f-825a-c0b878d1c24b
) 后的部分包含要删除的特定用户的凭据 ID。删除凭据
操作会显示确认屏幕,用户可以在其中确认同意删除凭据。
Keycloak 账户控制台 通常在删除第二因素凭据时使用 删除凭据 操作。如果您想直接从自己的应用程序中使用此操作,可以查看账户控制台中的示例。但是,最好依赖账户控制台,而不是从您自己的应用程序管理凭据。 |
可用操作
要查看所有可用操作,请登录到管理控制台,然后转到右上角,单击 Realm info
→ Provider info
选项卡 → 找到提供程序 required-action
。但请注意,根据在必需操作选项卡中为您的 realm 启用的操作,这可能会受到进一步限制。
搜索用户
搜索用户以查看有关用户的详细信息,例如用户的组和角色。
-
您位于用户所在的 realm 中。
默认搜索
-
在主菜单中单击 用户。将显示此 用户 页面。
-
在搜索框中键入您要搜索的用户的全名、姓氏、名字或电子邮件地址。搜索将返回所有符合您条件的用户。
用于匹配用户的条件取决于搜索框中使用的语法
-
"somevalue"
→ 执行字符串"somevalue"
的精确搜索; -
*somevalue*
→ 执行中缀搜索,类似于LIKE '%somevalue%'
数据库查询; -
somevalue*
或somevalue
→ 执行前缀搜索,类似于LIKE 'somevalue%'
数据库查询。
-
属性搜索
-
在主菜单中单击 用户。将显示此 用户 页面。
-
单击 默认搜索 按钮,并将其切换到 属性搜索。
-
单击 选择属性 按钮,并指定要搜索的属性。
-
选中 精确搜索 复选框以执行精确匹配,或保持未选中状态以对属性值使用中缀搜索。
-
单击 搜索 按钮以执行搜索。它将返回所有符合条件的用户。
在 用户 页面中执行的搜索涵盖 Keycloak 的数据库和配置的用户联合后端,例如 LDAP。在联合后端中找到的用户如果尚未存在于 Keycloak 的数据库中,将被导入到 Keycloak 的数据库中。 |
-
有关用户联合的更多信息,请参阅 用户联合。
删除用户
您可以删除不再需要访问应用程序的用户。如果用户被删除,则用户个人资料和数据也将被删除。
-
在菜单中单击 用户。将显示 用户 页面。
-
单击 查看所有用户 以查找要删除的用户。
或者,您可以使用搜索栏查找用户。 -
从要删除的用户旁边的操作菜单中单击 删除 并确认删除。
允许用户删除帐户
如果您在管理控制台中启用此功能,最终用户和应用程序可以在账户控制台中删除他们的帐户。启用此功能后,您可以将该功能授予特定用户。
启用删除帐户功能
您可以在 必需操作 选项卡上启用此功能。
-
点击菜单中的 身份验证。
-
点击 Required Actions(必需的操作) 选项卡。
-
在 删除帐户 行中选择 已启用。
必需操作选项卡上的删除帐户
模拟用户
具有适当权限的管理员可以模拟用户。例如,如果用户在应用程序中遇到错误,管理员可以模拟用户来调查或重现该问题。
realm 中具有 impersonation
角色的任何用户都可以模拟用户。
-
在菜单中点击用户。
-
单击要模拟的用户。
-
从 操作 列表中,选择 模拟。
-
如果管理员和用户在同一 realm 中,则管理员将被注销并自动以被模拟用户的身份登录。
-
如果管理员和用户在不同的 realm 中,则管理员将保持登录状态,并且还将以该用户 realm 中用户的身份登录。
-
在这两种情况下,都会显示被模拟用户的 账户控制台。
-
有关分配管理权限的更多信息,请参阅 管理控制台访问控制 章节。
启用 reCAPTCHA
为了保护注册免受机器人的侵害,Keycloak 集成了 Google reCAPTCHA(请参阅 设置 Google reCAPTCHA)和 reCAPTCHA Enterprise(请参阅 设置 Google reCAPTCHA Enterprise)。默认主题 (register.ftl
) 支持 v2(可见、基于复选框)和 v3(基于分数、不可见)reCAPTCHA(请参阅 选择合适的 reCAPTCHA 密钥类型)。
设置 Google reCAPTCHA
-
在浏览器中输入以下 URL
https://www.google.com/recaptcha/admin/create
-
创建 reCAPTCHA,并在 Challenge v2(可见复选框)或 Score-based v3(不可见)之间进行选择,以获取您的 reCAPTCHA 站点密钥和密钥。记下它们以供本过程将来使用。
默认情况下不支持 localhost 域。如果您希望继续支持它们进行开发,您可以将它们添加到站点密钥的受支持域列表中。 -
导航到 Keycloak 管理控制台。
-
点击菜单中的 身份验证。
-
点击 流程 选项卡。
-
从列表中选择 注册。
-
将 reCAPTCHA 要求设置为 必需。这将启用 reCAPTCHA。
-
单击 reCAPTCHA 行中的 齿轮图标 ⚙️。
reCAPTCHA 配置-
输入从 Google reCAPTCHA 网站生成的 reCAPTCHA 站点密钥。
-
输入从 Google reCAPTCHA 网站生成的 reCAPTCHA 密钥。
-
根据您的站点密钥类型切换 reCAPTCHA v3:对于基于分数的 reCAPTCHA (v3),切换为“开”;对于 challenge reCAPTCHA (v2),切换为“关”。
-
(可选)切换 使用 recaptcha.net 以使用
www.recaptcha.net
而不是www.google.com
域来获取 Cookie。有关更多信息,请参阅 reCAPTCHA 常见问题解答。
-
-
授权 Google 将注册页面用作 iframe。
在 Keycloak 中,网站不能在 iframe 中包含登录页面对话框。此限制是为了防止点击劫持攻击。您需要更改 Keycloak 中设置的默认 HTTP 响应标头。 -
在菜单中单击“Realm 设置”。
-
单击 安全防御 选项卡。
-
在 X-Frame-Options 标头的字段中输入
https://www.google.com
(如果您启用了 使用 recaptcha.net,则输入https//www.recaptcha.net
)。 -
在 Content-Security-Policy 标头的字段中输入
https://www.google.com
(如果您启用了 使用 recaptcha.net,则输入https//www.recaptcha.net
)。
-
设置 Google reCAPTCHA Enterprise
-
在浏览器中输入以下 URL
https://developers.google.com/recaptcha/
-
为“网站”平台创建一个密钥,并选择所需的密钥类型。对于 v3 reCAPTCHA(不可见),保留默认设置,或者对于 v2 reCAPTCHA(可见),切换 使用复选框 challenge。记下站点密钥以供本过程将来使用。
localhost 默认情况下有效。您不必指定域。 -
在您的 Google Cloud 项目中,转到 凭据 并创建一个 API 密钥。
为了更好的安全性,单击 编辑 API 密钥 并添加 API 限制,以将密钥限制为仅 reCAPTCHA Enterprise API。 -
导航到 Keycloak 管理控制台。
-
点击菜单中的 身份验证。
-
点击 流程 选项卡。
-
复制“注册”流程。
-
将新流程绑定到 注册流程。
-
编辑新流程
-
删除 reCAPTCHA 步骤。
-
将步骤 reCAPTCHA Enterprise 添加为“注册表单”(流程的第一步)的子步骤。
-
-
将 reCAPTCHA Enterprise 要求设置为 必需。
-
单击 reCAPTCHA Enterprise 行中的 齿轮图标 ⚙️。
reCAPTCHA Enterprise 配置-
输入您的 Google Cloud 控制台项目的 Recaptcha 项目 ID。
-
输入在本过程开始时生成的 Recaptcha 站点密钥。
-
输入在本过程开始时生成的 Recaptcha API 密钥。
-
根据您的站点密钥类型切换 reCAPTCHA v3:对于基于分数的 reCAPTCHA (v3),切换为“开”;对于 challenge reCAPTCHA (v2),切换为“关”。
-
(可选)根据您的需要自定义 最低分数阈值。将其设置为用户在 reCAPTCHA 上应达到的最低分数(介于 0.0 和 1.0 之间)才能被允许注册。请参阅 解释分数。
-
(可选)切换 使用 recaptcha.net 以使用
www.recaptcha.net
而不是www.google.com
域来获取 Cookie。有关更多信息,请参阅 reCAPTCHA 常见问题解答。
-
-
授权 Google 将注册页面用作 iframe。有关详细步骤,请参阅 设置 Google reCAPTCHA 的最后几个步骤。
-
有关扩展和创建主题的更多信息,请参阅服务器开发人员指南。
Keycloak 收集的个人数据
默认情况下,Keycloak 收集以下数据
-
基本用户个人资料数据,例如用户电子邮件、名字和姓氏。
-
用于社交帐户的基本用户个人资料数据以及使用社交登录时对社交帐户的引用。
-
出于审计和安全目的收集的设备信息,例如 IP 地址、操作系统名称和浏览器名称。
Keycloak 中收集的信息是高度可定制的。进行自定义时,以下准则适用
-
注册和帐户表单可以包含自定义字段,例如生日、性别和国籍。管理员可以将 Keycloak 配置为从社交提供商或用户存储提供商(例如 LDAP)检索数据。
-
Keycloak 收集用户凭据,例如密码、OTP 代码和 WebAuthn 公钥。此信息已加密并保存在数据库中,因此 Keycloak 管理员不可见。每种类型的凭据都可以包含非机密元数据,这些元数据对管理员可见,例如用于哈希密码的算法以及用于哈希密码的哈希迭代次数。
-
启用授权服务和 UMA 支持后,Keycloak 可以保存有关特定用户是所有者的某些对象的信息。
管理用户会话
当用户登录 realm 时,Keycloak 会为每个用户维护一个用户会话,并记住用户在会话中访问的每个客户端。Realm 管理员可以对每个用户会话执行多项操作
-
查看 realm 的登录统计信息。
-
查看活跃用户以及他们的登录位置。
-
将用户从其会话中注销。
-
撤销令牌。
-
设置令牌超时。
-
设置会话超时。
管理会话
要查看 Keycloak 中活动客户端和会话的顶层视图,请单击菜单中的 Sessions(会话)。
注销所有活动会话
您可以注销 realm 中的所有用户。从 Action(操作)列表中,选择 Sign out all active sessions(注销所有活动会话)。所有 SSO cookie 都将失效。Keycloak 通过使用 Keycloak OIDC 客户端适配器通知客户端注销事件。在活动浏览器会话中请求身份验证的客户端必须重新登录。SAML 等客户端类型不会收到后通道注销请求。
单击 Sign out all active sessions(注销所有活动会话)不会撤销未完成的访问令牌。未完成的令牌必须自然过期。对于使用 Keycloak OIDC 客户端适配器的客户端,您可以推送撤销策略来撤销令牌,但这不适用于其他适配器。 |
撤销活动会话
如果您的系统遭到入侵,您可以撤销所有活动会话和访问令牌。
-
单击菜单中的 Sessions(会话)。
-
从 Actions(操作)列表中,选择 Revocation(撤销)。
撤销 -
使用此控制台指定会话或在该日期和时间之前颁发的令牌失效的日期和时间。
-
单击 Set to now(设置为现在)将策略设置为当前日期和时间。
-
单击 Push(推送)以将此撤销策略推送到任何已注册且使用 Keycloak OIDC 客户端适配器的 OIDC 客户端。
-
会话和令牌超时
Keycloak 在 Realm settings(Realm 设置)菜单中的 Sessions(会话)和 Tokens(令牌)选项卡中,包含了对会话、cookie 和令牌超时的控制。
配置 | 描述 |
---|---|
SSO 会话空闲 |
此设置仅适用于 OIDC 客户端。如果用户不活动时间超过此超时时间,则用户会话将失效。当客户端请求身份验证或发送刷新令牌请求时,此超时值会重置。Keycloak 会在空闲超时时间中增加一个时间窗口,然后会话失效才会生效。请参阅本节稍后的注意。 |
SSO 会话最大值 |
用户会话过期的最长时间。 |
SSO 会话空闲记住我 |
此设置类似于标准的 SSO 会话空闲配置,但专门针对启用 Remember Me(记住我)的登录。用户在登录时单击 Remember Me(记住我)时,可以指定更长的会话空闲超时时间。此设置是可选配置,如果其值不大于零,则它使用与 SSO 会话空闲配置相同的空闲超时时间。 |
SSO 会话最大值记住我 |
此设置类似于标准的 SSO 会话最大值,但专门针对 Remember Me(记住我)登录。用户在登录时单击 Remember Me(记住我)时,可以指定更长的会话。此设置是可选配置,如果其值不大于零,则它使用与 SSO 会话最大值配置相同的会话生命周期。 |
客户端会话空闲 |
客户端会话的空闲超时时间。如果用户不活动时间超过此超时时间,则客户端会话将失效,并且刷新令牌请求会延长空闲超时时间。此设置永远不会影响通用的 SSO 用户会话,它是唯一的。请注意,SSO 用户会话是零个或多个客户端会话的父级,对于用户登录的每个不同的客户端应用程序,都会创建一个客户端会话。此值应指定比 SSO 会话空闲 更短的空闲超时时间。用户可以在 Advanced Settings(高级设置)客户端选项卡中为单个客户端覆盖它。此设置是可选配置,当设置为零时,它使用与 SSO 会话空闲配置相同的空闲超时时间。 |
客户端会话最大值 |
客户端会话的最长时间,以及刷新令牌过期和失效之前的最长时间。与之前的选项一样,此设置永远不会影响 SSO 用户会话,并且应指定比 SSO 会话最大值 更短的值。用户可以在 Advanced Settings(高级设置)客户端选项卡中为单个客户端覆盖它。此设置是可选配置,当设置为零时,它使用与 SSO 会话最大值配置相同的最大超时时间。 |
离线会话空闲 |
此设置用于离线访问。会话保持空闲的时间量,超过此时间后,Keycloak 将撤销其离线令牌。Keycloak 会在空闲超时时间中增加一个时间窗口,然后会话失效才会生效。请参阅本节稍后的注意。 |
离线会话最大值限制 |
此设置用于离线访问。如果此标志为 Enabled(启用),则“离线会话最大值”可以控制离线令牌保持活动状态的最长时间,而与用户活动无关。如果此标志为 Disabled(禁用),则离线会话永远不会因生命周期而过期,而只会因空闲而过期。激活此选项后,可以配置离线会话最大值(realm 级别的全局选项)和 Client Offline Session Max(客户端“高级设置”选项卡中的特定客户端级别选项)。 |
离线会话最大值 |
此设置用于离线访问,它是 Keycloak 撤销相应离线令牌之前的最长时间。此选项控制离线令牌保持活动状态的最长时间,而与用户活动无关。 |
登录超时 |
登录必须花费的总时间。如果身份验证花费的时间超过此时间,则用户必须重新开始身份验证过程。 |
登录操作超时 |
用户在身份验证过程中的任何一个页面上可以花费的最长时间。 |
配置 | 描述 |
---|---|
默认签名算法 |
用于为 realm 分配令牌的默认算法。 |
撤销刷新令牌 |
当 Enabled(启用)时,Keycloak 将撤销刷新令牌并颁发客户端必须使用的另一个令牌。此操作适用于执行刷新令牌流程的 OIDC 客户端。 |
访问令牌生命周期 |
当 Keycloak 创建 OIDC 访问令牌时,此值控制令牌的生命周期。 |
隐式流程的访问令牌生命周期 |
对于隐式流程,Keycloak 不提供刷新令牌。对于通过隐式流程创建的访问令牌,存在单独的超时时间。 |
客户端登录超时 |
客户端必须在 OIDC 中完成授权码流程的最长时间。 |
用户发起的动作生命周期 |
用户动作权限过期的最长时间。保持此值较短,因为用户通常会对自行创建的动作做出快速反应。 |
默认管理员发起的动作生命周期 |
管理员发送给用户的动作权限过期的最长时间。保持此值较长,以便管理员可以向离线用户发送电子邮件。管理员可以在颁发令牌之前覆盖默认超时时间。 |
电子邮件验证 |
指定电子邮件验证的独立超时时间。 |
IdP 帐户电子邮件验证 |
指定 IdP 帐户电子邮件验证的独立超时时间。 |
忘记密码 |
指定忘记密码的独立超时时间。 |
执行操作 |
指定执行操作的独立超时时间。 |
以下逻辑仅在持久用户会话未激活时应用 对于空闲超时,会话处于活动状态的时间窗口为两分钟。例如,当您将超时时间设置为 30 分钟时,会话将在 32 分钟后过期。 在集群和跨数据中心环境中,某些情况下需要执行此操作,在这些环境中,令牌在一个集群节点上刷新,时间比过期时间提前一小段时间,而其他集群节点错误地认为会话已过期,因为它们尚未收到来自刷新节点的关于成功刷新的消息。 |
离线访问
在离线访问登录期间,客户端应用程序请求离线令牌而不是刷新令牌。客户端应用程序保存此离线令牌,如果用户注销,则可以使用它进行将来的登录。如果您的应用程序需要在用户未在线时代表用户执行离线操作,则此操作非常有用。例如,定期数据备份。
客户端应用程序负责将离线令牌持久化存储,然后使用它从 Keycloak 服务器检索新的访问令牌。
刷新令牌和离线令牌之间的区别在于,离线令牌永不过期,并且不受 SSO 会话空闲
超时和 SSO 会话最大值
生命周期限制。离线令牌在用户注销后仍然有效。您必须每三十天至少使用一次离线令牌进行刷新令牌操作,或者按照离线会话空闲的值进行操作。
当使用离线访问时,客户端空闲和最大超时可以在客户端级别被覆盖。客户端 Advanced Settings(高级设置)选项卡中的 Client Offline Session Idle(客户端离线会话空闲)和 Client Offline Session Max(客户端离线会话最大值)选项允许您为特定应用程序设置更短的离线超时时间。请注意,客户端会话值也控制刷新令牌过期时间,但它们永远不会影响全局离线用户 SSO 会话。只有当 realm 级别 Offline Session Max Limited(离线会话最大值限制)设置为 Enabled(启用)时,才会在客户端中评估 Client Offline Session Max(客户端离线会话最大值)选项。
如果您启用撤销刷新令牌选项,则每个离线令牌只能使用一次。刷新后,您必须存储来自刷新响应的新离线令牌,而不是之前的令牌。
用户可以在用户帐户控制台中查看和撤销 Keycloak 授予他们的离线令牌。管理员可以在管理控制台的 Consents
(授权许可)选项卡中撤销单个用户的离线令牌。管理员可以在每个客户端的 Offline Access
(离线访问)选项卡中查看所有已颁发的离线令牌。管理员可以通过设置撤销策略来撤销离线令牌。
要颁发离线令牌,用户必须具有 realm 级 offline_access
角色的角色映射。客户端还必须在其范围中具有该角色。客户端必须将 offline_access
客户端范围添加为角色的 Optional client scope
(可选客户端范围),默认情况下已完成此操作。
客户端可以通过在向 Keycloak 发送授权请求时添加参数 scope=offline_access
来请求离线令牌。当您使用 Keycloak OIDC 客户端适配器访问应用程序的安全 URL(例如,https://#:8080/customer-portal/secured?scope=offline_access)时,它会自动添加此参数。如果您在身份验证请求正文中包含 scope=offline_access
,则直接访问授权和服务帐户也支持离线令牌。
默认情况下,Keycloak 将其离线用户和离线客户端会话的内部缓存限制为 10000 个条目,这将减少离线会话的总体内存使用量。从内存中逐出的项目将在需要时按需从数据库加载。要为缓存设置不同的大小,请编辑 Keycloak 的缓存配置文件,为这些缓存设置 <memory max-count="..."/>
。
如果您禁用了 persistent-user-sessions
功能,则可以使用配置选项来缩短导入的离线会话的生命周期,从而降低内存需求。此类会话将在指定的生命周期后从 Infinispan 缓存中逐出,但仍可在数据库中使用。这将降低内存消耗,尤其是在部署了大量离线会话的情况下。
要指定离线用户会话的生命周期覆盖,请使用以下参数启动 Keycloak 服务器
--spi-user-sessions-infinispan-offline-session-cache-entry-lifespan-override=<lifespan-in-seconds>
离线客户端会话类似
--spi-user-sessions-infinispan-offline-client-session-cache-entry-lifespan-override=<lifespan-in-seconds>
瞬态会话
您可以在 Keycloak 中执行瞬态会话。当使用瞬态会话时,Keycloak 在成功身份验证后不会创建用户会话。Keycloak 为当前请求的范围创建一个临时的瞬态会话,该请求成功验证了用户身份。Keycloak 可以在身份验证后使用瞬态会话运行 协议映射器。
当令牌通过瞬态会话颁发时,令牌的 sid
和 session_state
通常为空。因此,在瞬态会话期间,客户端应用程序无法刷新令牌或验证特定会话。有时这些操作是不必要的,因此您可以避免持久化用户会话而产生的额外资源使用。此会话节省了性能、内存和网络通信(在集群和跨数据中心环境)资源。
目前,仅在禁用令牌刷新的服务帐户身份验证期间自动使用瞬态会话。请注意,除非通过客户端开关 Use refresh tokens for client credentials grant
显式启用令牌刷新,否则在服务帐户身份验证期间会自动禁用令牌刷新。
使用角色和组分配权限
角色和组具有相似的目的,即为用户提供访问权限和使用应用程序的权限。组是用户的集合,您可以在其中应用角色和属性。角色定义特定的应用程序权限和访问控制。
一个角色通常适用于一种类型的用户。例如,一个组织可能包括 admin
、user
、manager
和 employee
角色。应用程序可以将访问权限和许可分配给角色,然后将多个用户分配给该角色,以便用户具有相同的访问权限和许可。例如,Admin Console 具有允许用户访问 Admin Console 不同部分的角色。
角色有一个全局命名空间,每个客户端也有其自己的专用命名空间,可以在其中定义角色。
创建 realm 角色
Realm 级别的角色是定义角色的命名空间。要查看角色列表,请单击菜单中的 Realm Roles(Realm 角色)。
-
单击 Create Role(创建角色)。
-
输入 Role Name(角色名称)。
-
输入 Description(描述)。
-
点击 保存。
description(描述) 字段可以通过使用 ${var-name}
字符串指定替换变量来实现本地化。本地化值在主题属性文件中配置到您的主题。有关更多详细信息,请参阅 Server Developer Guide(服务器开发者指南)。
将角色转换为复合角色
任何 realm 或客户端级别的角色都可以成为复合角色。复合角色是指具有一个或多个关联角色的角色。当复合角色映射到用户时,用户将获得与复合角色关联的角色。这种继承是递归的,因此用户也会继承任何复合角色的复合角色。但是,我们建议不要过度使用复合角色。
-
单击菜单中的 Realm Roles(Realm 角色)。
-
单击要转换的角色。
-
从 Action(操作) 列表中,选择 Add associated roles(添加关联角色)。
角色选择 UI 将显示在页面上,您可以将 realm 级别和客户端级别的角色与您正在创建的复合角色关联。
在此示例中,employee(员工) realm 级别角色与 developer(开发者) 复合角色关联。任何具有 developer(开发者) 角色的用户也将继承 employee(员工) 角色。
在创建令牌和 SAML 断言时,任何复合角色也会将其关联角色添加到发送回客户端的身份验证响应的声明和断言中。 |
分配角色映射
您可以通过用户的 Role Mappings(角色映射) 选项卡为用户分配角色映射。
-
在菜单中点击用户。
-
单击要执行角色映射的用户。
-
单击 Role mappings(角色映射) 选项卡。
-
单击 Assign role(分配角色)。
-
从对话框中选择要分配给用户的角色。
-
单击 分配。
在前面的示例中,我们将复合角色 developer(开发者) 分配给用户。该角色是在 复合角色 主题中创建的。
当分配 developer(开发者) 角色时,与 developer(开发者) 复合角色关联的 employee(员工) 角色将显示为 Inherited(已继承) “True”。Inherited(已继承) 角色是显式分配给用户的角色以及从复合角色继承的角色。
使用默认角色
当用户通过 身份代理 创建或导入时,使用默认角色自动分配用户角色映射。
-
在菜单中单击“Realm 设置”。
-
单击 User registration(用户注册) 选项卡。
默认角色
此屏幕截图显示已存在一些默认角色。
角色范围映射
在创建 OIDC 访问令牌或 SAML 断言时,用户角色映射将成为令牌或断言中的声明。应用程序使用这些声明来对应用程序控制的资源做出访问决策。Keycloak 对访问令牌进行数字签名,应用程序重用这些令牌来调用远程安全 REST 服务。但是,这些令牌具有相关风险。攻击者可以获取这些令牌并使用其权限来危害您的网络。为防止这种情况,请使用角色范围映射。
角色范围映射限制了访问令牌内声明的角色。当客户端请求用户身份验证时,它收到的访问令牌仅包含为客户端范围显式指定的角色映射。结果是,每个单独访问令牌的权限受到限制,而不是让客户端访问用户的所有权限。
默认情况下,每个客户端都获取用户的所有角色映射。您可以查看客户端的角色映射。
-
单击菜单中的 Clients(客户端)。
-
单击客户端以转到详细信息。
-
单击 Client scopes(客户端范围) 选项卡。
-
单击带有 Dedicated scope and mappers for this client(此客户端的专用范围和映射器) 的行中的链接
-
单击 Scope(范围) 选项卡。
默认情况下,范围的有效角色是 realm 中声明的每个角色。要更改此默认行为,请将 Full Scope Allowed(允许完整范围) 切换为 OFF(关闭),并在每个客户端中声明您需要的特定角色。您还可以使用 客户端范围 为一组客户端定义相同的角色范围映射。
有关将角色添加到令牌的算法的详细信息,请参阅 令牌角色映射部分。
组
Keycloak 中的组管理每个用户的通用属性集和角色映射。用户可以是任意数量的组的成员,并继承分配给每个组的属性和角色映射。
要管理组,请单击菜单中的 Groups(组)。
组是分层的。一个组可以有多个子组,但一个组只能有一个父组。子组从其父组继承属性和角色映射。用户也从其父组继承属性和角色映射。
如果您有一个父组和一个子组,并且一个用户仅属于子组,则子组中的用户将继承父组和子组的属性和角色映射。
组的层次结构有时使用组路径表示。路径是表示特定组层次结构的完整名称列表,从上到下并用斜杠 /
分隔(类似于文件系统中的文件)。例如,路径可以是 /top/level1/level2
,这意味着 top
是顶级组,是 level1
的父组,而 level1
又是 level2
的父组。此路径明确地表示组 level2
的层次结构。
由于历史原因,Keycloak 不会转义组名称本身中的斜杠。因此,top
下名为 level1/group
的组使用路径 /top/level1/group
,这具有误导性。可以使用选项 --spi-group-jpa-escape-slashes-in-group-path
将 Keycloak 启动为 true
,然后名称中的斜杠将使用字符 ~
转义。转义字符标记斜杠是名称的一部分,没有层次结构意义。当转义时,之前的路径示例将为 /top/level1~/group
。
bin/kc.[sh|bat] start --spi-group-jpa-escape-slashes-in-group-path=true
以下示例包括一个顶级 Sales(销售) 组和一个子级 North America(北美) 子组。
要添加组
-
单击组。
-
单击 Create group(创建组)。
-
输入组名称。
-
单击“创建”。
-
单击组名称。
将显示组管理页面。
组
您定义的属性和角色映射由组以及作为该组成员的用户继承。
要将用户添加到组
-
在菜单中点击用户。
-
单击要执行角色映射的用户。如果未显示用户,请单击 View all users(查看所有用户)。
-
单击 Groups(组)。
-
单击 Join Group(加入组)。
-
从对话框中选择一个组。
-
从 Available Groups(可用组) 树中选择一个组。
-
单击 Join(加入)。
加入组
要从用户中删除组
-
在菜单中点击用户。
-
单击要从组中删除的用户。
-
单击组表格行上的 Leave(离开)。
在此示例中,用户 jimlincoln 在 North America(北美) 组中。您可以在该组的 Members(成员) 选项卡下看到显示的 jimlincoln。
组与角色的比较
组和角色有一些相似之处和不同之处。在 Keycloak 中,组是用户的集合,您可以在其中应用角色和属性。角色定义用户类型,应用程序将权限和访问控制分配给角色。
复合角色 与组类似,因为它们提供相同的功能。它们之间的区别在于概念。复合角色将权限模型应用于一组服务和应用程序。使用复合角色来管理应用程序和服务。
组侧重于用户集合及其在组织中的角色。使用组来管理用户。
使用默认组
要自动为通过 身份代理 创建或导入的任何用户分配组成员资格,您可以使用默认组。
-
在菜单中单击“Realm 设置”。
-
单击 User registration(用户注册) 选项卡。
-
单击 Default Groups(默认组) 选项卡。
默认组
此屏幕截图显示已存在一些默认组。
配置身份验证
本章涵盖了几个身份验证主题。这些主题包括
-
强制执行严格的密码和一次性密码 (OTP) 策略。
-
管理不同的凭据类型。
-
使用 Kerberos 登录。
-
禁用和启用内置凭据类型。
密码策略
当 Keycloak 创建 realm 时,它不会将密码策略与 realm 关联。您可以设置一个简单的密码,对其长度、安全性或复杂性没有限制。简单的密码在生产环境中是不可接受的。Keycloak 通过管理控制台提供了一组密码策略。
-
点击菜单中的 身份验证。
-
点击 策略 (Policies) 选项卡。
-
在 添加策略 (Add policy) 下拉框中选择要添加的策略。
-
输入适用于所选策略的值。
-
点击 保存。
密码策略
保存策略后,Keycloak 会对新用户强制执行该策略。
新策略对现有用户无效。因此,请确保在 realm 创建之初就设置密码策略,或者向现有用户添加 “更新密码 (Update password)” 操作,或者使用 “密码过期 (Expire password)” 以确保用户在接下来的 “N” 天内更新其密码,这将实际适应新的密码策略。 |
密码策略类型
HashAlgorithm
密码不会以明文形式存储。在存储或验证之前,Keycloak 使用标准哈希算法对密码进行哈希处理。
下表显示了支持的密码哈希算法。
哈希算法 | 描述 |
---|---|
|
Argon2(非 FIPS 部署的默认算法) |
|
PBKDF2 with SHA512(FIPS 部署的默认算法) |
|
PBKDF2 with SHA256 |
|
PBKDF2 with SHA1(已弃用) |
强烈建议尽可能使用 Argon2,因为与 PBKDF2 相比,它对 CPU 的要求显著降低,同时更安全。
可以使用 --spi-password-hashing-provider-default=<algorithm>
配置服务器的默认密码哈希算法。
为了防止过度的内存和 CPU 使用率,Argon2 并行计算哈希值默认限制为 JVM 可用的核心数。要配置 Argon2 哈希提供程序,请使用其提供程序选项。
请参阅 服务器开发人员指南 (Server Developer Guide),了解如何添加您自己的哈希算法。
如果您更改哈希算法,则存储中的密码哈希值在用户登录之前不会更改。 |
哈希迭代次数
指定 Keycloak 在存储或验证之前对密码进行哈希处理的次数。默认值为 -1,它使用所选哈希算法的默认哈希迭代次数,如下表所示。
哈希算法 | 默认哈希迭代次数 |
---|---|
|
5 |
|
210,000 |
|
600,000 |
|
1,300,000 |
在大多数情况下,哈希迭代次数不应从建议的默认值更改。较低的迭代次数提供的安全性不足,而较高的迭代次数会导致更高的 CPU 功耗要求。 |
正则表达式
密码必须匹配一个或多个定义的 Java 正则表达式模式。有关这些表达式的语法,请参阅 Java 的正则表达式文档。
密码黑名单
密码不得在黑名单文件中。
-
黑名单文件是 UTF-8 纯文本文件,使用 Unix 行尾符。每一行代表一个被列入黑名单的密码。
-
Keycloak 以不区分大小写的方式比较密码。
-
黑名单文件的值必须是黑名单文件的名称,例如,
100k_passwords.txt
。 -
默认情况下,黑名单文件相对于
${kc.home.dir}/data/password-blacklists/
解析。使用以下方式自定义此路径-
keycloak.password.blacklists.path
系统属性。 -
passwordBlacklist
策略 SPI 配置的blacklistsPath
属性。要使用 CLI 配置黑名单文件夹,请使用--spi-password-policy-password-blacklist-blacklists-path=/path/to/blacklistsFolder
。
-
当前实现使用 BloomFilter 进行快速且内存高效的包含性检查,例如给定的密码是否包含在黑名单中,但可能存在误报。
-
默认情况下,使用
0.01%
的误报概率。 -
要通过 CLI 配置更改误报概率,请使用
--spi-password-policy-password-blacklist-false-positive-probability=0.00001
。
最大身份验证年龄
指定用户在无需重新身份验证的情况下更新密码的最大身份验证年龄(以秒为单位)。值为 0
表示用户在更新密码之前始终必须使用当前密码重新进行身份验证。有关此策略的一些其他详细信息,请参阅 AIA 部分。
在管理控制台的 必需操作 (Required Actions) 选项卡中配置必需操作 更新密码 (Update Password) 时,也可以配置最大身份验证年龄。更好的选择是使用必需操作进行配置,因为 *最大身份验证年龄* 密码策略将来可能会被弃用/删除。 |
一次性密码 (OTP) 策略
Keycloak 具有多个策略,用于设置 FreeOTP 或 Google Authenticator 一次性密码生成器。
-
点击菜单中的 身份验证。
-
点击 策略 (Policy) 选项卡。
-
点击 OTP 策略 (OTP Policy) 选项卡。
Keycloak 在 OTP 设置页面上生成一个 QR 码,该 QR 码基于 OTP 策略 (OTP Policy) 选项卡中配置的信息。FreeOTP 和 Google Authenticator 在配置 OTP 时扫描 QR 码。
基于时间或基于计数器的一次性密码
Keycloak 中 OTP 生成器可用的算法是基于时间和基于计数器的。
使用基于时间的一次性密码 (TOTP),令牌生成器将哈希当前时间和共享密钥。服务器通过比较时间窗口内的哈希值与提交的值来验证 OTP。TOTP 在短时间内有效。
使用基于计数器的一次性密码 (HOTP),Keycloak 使用共享计数器而不是当前时间。Keycloak 服务器在每次成功的 OTP 登录时递增计数器。有效的 OTP 在成功登录后会更改。
TOTP 比 HOTP 更安全,因为可匹配的 OTP 在短时间内有效,而 HOTP 的 OTP 在不确定的时间内有效。HOTP 比 TOTP 更用户友好,因为输入 OTP 没有时间限制。
HOTP 每次服务器递增计数器时都需要数据库更新。在高负载期间,此更新会消耗身份验证服务器的性能。为了提高效率,TOTP 不会记住使用过的密码,因此无需执行数据库更新。缺点是在有效时间间隔内可以重用 TOTP。
身份验证流程
身份验证流程 是登录、注册和其他 Keycloak 工作流程期间的身份验证、屏幕和操作的容器。
内置流程
Keycloak 有几个内置流程。您无法修改这些流程,但可以更改流程的需求以满足您的需要。
-
点击菜单中的 身份验证。
-
点击列表中的 Browser 项以查看详细信息。
身份验证类型
要执行的身份验证或操作的名称。如果身份验证已缩进,则它位于子流程中。它可能会执行,也可能不会执行,具体取决于其父级的行为。
-
Cookie
用户首次成功登录时,Keycloak 会设置会话 Cookie。如果 Cookie 已设置,则此身份验证类型成功。由于 Cookie 提供程序返回成功,并且此流程级别的每次执行都是备选的,因此 Keycloak 不会执行任何其他操作。这会导致成功登录。
-
Kerberos
此身份验证器默认情况下已禁用,并在浏览器流程期间跳过。
-
身份提供商重定向器
此操作通过 操作 (Actions) > 配置 (Config) 链接进行配置。它重定向到另一个 IdP 进行 身份代理。
-
表单
由于此子流程标记为备选,如果 Cookie 身份验证类型通过,则不会执行此子流程。此子流程包含需要执行的其他身份验证类型。Keycloak 加载此子流程的执行并处理它们。
第一个执行是 用户名密码表单 (Username Password Form),这是一种身份验证类型,用于呈现用户名和密码页面。它被标记为必需,因此用户必须输入有效的用户名和密码。
第二个执行是 Browser - Conditional OTP 子流程。此子流程是有条件的,并根据 Condition - User Configured 执行的结果执行。如果结果为 true,Keycloak 会为此子流程加载执行并处理它们。
下一个执行是 Condition - User Configured 身份验证。此身份验证检查 Keycloak 是否为用户配置了流程中的其他执行。只有当用户配置了 OTP 凭据时,Browser - Conditional OTP 子流程才会执行。
最后的执行是 OTP Form。Keycloak 将此执行标记为必需的,但它仅在用户设置了 OTP 凭据时运行,因为在有条件的子流程中进行了设置。如果未设置,用户将不会看到 OTP 表单。
创建流程
设计流程时,重要的功能和安全注意事项适用。
要创建流程,请执行以下操作
-
点击菜单中的 身份验证。
-
点击 创建流程。
您可以复制然后修改现有流程。点击“操作列表”(行尾的三个点),点击 复制,然后输入新流程的名称。 |
创建新流程时,您必须首先创建具有以下选项的顶层流程
- 名称
-
流程的名称。
- 描述
-
您可以为流程设置的描述。
- 顶层流程类型
-
流程的类型。类型 client 仅用于客户端(应用程序)的身份验证。对于所有其他情况,请选择 basic。
当 Keycloak 创建流程后,Keycloak 会显示 添加步骤 和 添加子流程 按钮。
三个因素决定了流程和子流程的行为。
-
流程和子流程的结构。
-
流程内的执行
-
子流程和执行中设置的要求。
执行具有各种各样的操作,从发送重置电子邮件到验证 OTP。使用 添加步骤 按钮添加执行。
身份验证执行可以选择配置参考值。身份验证方法参考 (AMR) 协议映射器可以利用此值来填充 OIDC 访问令牌和 ID 令牌中的 amr 声明(有关 AMR 声明的更多信息,请参阅 RFC-8176)。当为客户端配置了身份验证方法参考 (AMR) 协议映射器时,它将使用用户在身份验证流程期间成功完成的任何身份验证器执行的参考值来填充 amr 声明。
存在两种类型的执行,自动执行 和 交互式执行。自动执行 类似于 Cookie 执行,并将自动在流程中执行其操作。交互式执行 会暂停流程以获取输入。成功执行的执行将其状态设置为成功。要使流程完成,它至少需要一个状态为成功的执行。
您可以使用 添加子流程 按钮将子流程添加到顶层流程。添加子流程 按钮显示 创建执行流程 页面。此页面类似于 创建顶层表单 页面。区别在于 流程类型 可以是 basic(默认)或 form。form 类型构建一个为用户生成表单的子流程,类似于内置的 Registration 流程。子流程的成功取决于其执行的评估结果,包括其包含的子流程。有关子流程如何工作的深入解释,请参阅 执行要求部分。
添加执行后,检查要求是否具有正确的值。 |
流程中的所有元素在元素旁边都有一个 删除 选项。某些执行具有 ⚙️ 菜单项(齿轮图标)来配置执行。也可以使用 添加步骤 和 添加子流程 链接将执行和子流程添加到子流程。
由于执行顺序很重要,您可以通过拖动其名称来上下移动执行和子流程。
当您配置身份验证流程以确认您的设置中不存在安全漏洞时,请务必正确测试您的配置。我们建议您测试各种极端情况。例如,考虑在身份验证之前从用户的帐户中删除各种凭据时,测试用户的身份验证行为。 例如,当在流程中将第二因素身份验证器(如 OTP 表单或 WebAuthn 身份验证器)配置为 REQUIRED,并且用户没有特定类型的凭据时,用户将能够在身份验证本身期间设置特定凭据。这种情况意味着用户并非使用此凭据进行身份验证,因为他是在身份验证期间设置的。因此,对于浏览器身份验证,请确保使用某些第一因素凭据(如密码或 WebAuthn 无密码身份验证器)配置您的身份验证流程。 |
创建无密码浏览器登录流程
为了说明流程的创建,本节描述了创建高级浏览器登录流程。此流程的目的是允许用户选择使用 WebAuthn 以无密码方式登录,或使用密码和 OTP 进行双因素身份验证。
-
点击菜单中的 身份验证。
-
点击 流程 选项卡。
-
点击 创建流程。
-
输入
Browser Password-less
作为名称。 -
单击“创建”。
-
点击 添加执行。
-
从列表中选择 Cookie。
-
点击 添加。
-
为 Cookie 身份验证类型选择 备选,将其要求设置为备选。
-
点击 添加步骤。
-
从列表中选择 Kerberos。
-
点击 添加。
-
点击 添加步骤。
-
从列表中选择 身份提供商重定向器。
-
点击 添加。
-
为 身份提供商重定向器 身份验证类型选择 备选,将其要求设置为备选。
-
点击 添加子流程。
-
输入 Forms 作为名称。
-
点击 添加。
-
为 Forms 身份验证类型选择 备选,将其要求设置为备选。
与浏览器流程的公共部分 -
点击 Forms 执行的 + 菜单。
-
选择 添加步骤。
-
从列表中选择 用户名表单。
-
点击 添加。
在此阶段,表单需要用户名,但不需要密码。我们必须启用密码身份验证以避免安全风险。
-
点击 Forms 子流程的 + 菜单。
-
点击 添加子流程。
-
输入
Authentication
作为名称。 -
点击 添加。
-
为 Authentication 身份验证类型选择 必需,将其要求设置为必需。
-
点击 Authentication 子流程的 + 菜单。
-
点击 添加步骤。
-
从列表中选择 WebAuthn 无密码身份验证器。
-
点击 添加。
-
为 Webauthn 无密码身份验证器 身份验证类型选择 备选,将其要求设置为备选。
-
点击 Authentication 子流程的 + 菜单。
-
点击 添加子流程。
-
输入
Password with OTP
作为名称。 -
点击 添加。
-
为 Password with OTP 身份验证类型选择 备选,将其要求设置为备选。
-
点击 Password with OTP 子流程的 + 菜单。
-
点击 添加步骤。
-
从列表中选择 密码表单。
-
点击 添加。
-
为 密码表单 身份验证类型选择 必需,将其要求设置为必需。
-
点击 Password with OTP 子流程的 + 菜单。
-
点击 添加步骤。
-
从列表中选择 OTP 表单。
-
点击 添加。
-
为 OTP 表单 身份验证类型点击 必需,将其要求设置为必需。
最后,更改绑定。
-
点击屏幕顶部的 操作 菜单。
-
从菜单中选择 绑定流程。
-
点击 浏览器流程 下拉列表。
-
点击 保存。
输入用户名后,流程的工作方式如下
如果用户已记录 WebAuthn 无密码凭据,他们可以直接使用这些凭据登录。这是无密码登录。用户也可以选择 Password with OTP,因为 WebAuthn Passwordless
执行和 Password with OTP
流程都设置为 备选。如果它们设置为 必需,则用户必须输入 WebAuthn、密码和 OTP。
如果用户选择带有 WebAuthn passwordless
身份验证的 尝试其他方式 链接,则用户可以在 Password
和 Passkey
(WebAuthn 无密码) 之间进行选择。选择密码时,用户需要继续并使用分配的 OTP 登录。如果用户没有 WebAuthn 凭据,则用户必须输入密码,然后输入 OTP。如果用户没有 OTP 凭据,系统将要求他们记录一个。
由于 WebAuthn 无密码执行设置为 备选 而不是 必需,因此此流程永远不会要求用户注册 WebAuthn 凭据。要使用户拥有 Webauthn 凭据,管理员必须为用户添加必需的操作。通过以下方式执行此操作 创建如此高级的流程可能会产生副作用。例如,如果您启用重置用户密码的功能,则可以从密码表单访问此功能。在默认的
|
使用客户端策略选择身份验证流程
客户端策略 可用于根据特定条件(例如请求特定范围或使用 AuthenticationFlowSelectorExecutor
的 ACR(身份验证上下文类引用)与您偏好的条件相结合)动态选择身份验证流程。
AuthenticationFlowSelectorExecutor
允许您选择适当的身份验证流程,并设置选定流程完成后要应用的身份验证级别。
一种可能的配置涉及使用 ACRCondition
与 AuthenticationFlowSelectorExecutor
结合使用。此设置使您能够根据请求的 ACR 选择身份验证流程,并将 ACR 值包含在使用 ACR 到 LoA 映射 的令牌中。
有关更多详细信息,请参阅 客户端策略。
创建具有逐步提升机制的浏览器登录流程
本节描述了如何使用逐步提升机制创建高级浏览器登录流程。逐步提升身份验证的目的是允许基于用户的特定身份验证级别访问客户端或资源。
-
点击菜单中的 身份验证。
-
点击 流程 选项卡。
-
点击 创建流程。
-
输入
Browser Incl Step up Mechanism
作为名称。 -
点击 保存。
-
点击 添加执行。
-
从列表中选择 Cookie。
-
点击 添加。
-
为 Cookie 身份验证类型选择 备选,将其要求设置为备选。
-
点击 添加子流程。
-
输入 Auth Flow 作为名称。
-
点击 添加。
-
为 Auth Flow 身份验证类型点击 备选,将其要求设置为备选。
现在,您配置第一个身份验证级别的流程。
-
点击 Auth Flow 的 + 菜单。
-
点击 添加子流程。
-
输入
1st Condition Flow
作为名称。 -
点击 添加。
-
为 1st Condition Flow 身份验证类型点击 有条件的,将其要求设置为有条件的。
-
点击 1st Condition Flow 的 + 菜单。
-
点击 添加条件。
-
从列表中选择 条件 - 身份验证级别。
-
点击 添加。
-
为 条件 - 身份验证级别 身份验证类型点击 必需,将其要求设置为必需。
-
点击 ⚙️(齿轮图标)。
-
输入
Level 1
作为别名。 -
为身份验证级别 (LoA) 输入
1
。 -
将最大有效期设置为 36000。此值以秒为单位,相当于 10 小时,这是领域中设置的默认
SSO 会话最大时长
超时。因此,当用户使用此级别进行身份验证时,后续 SSO 登录可以重用此级别,并且用户无需使用此级别进行身份验证,直到用户会话结束,默认情况下为 10 小时。 -
点击 保存
配置第一个身份验证级别的条件 -
点击 1st Condition Flow 的 + 菜单。
-
点击 添加步骤。
-
从列表中选择 用户名密码表单。
-
点击 添加。
现在,您配置第二个身份验证级别的流程。
-
点击 Auth Flow 的 + 菜单。
-
点击 添加子流程。
-
输入
2nd Condition Flow
作为别名。 -
点击 添加。
-
为 2nd Condition Flow 身份验证类型点击 有条件的,将其要求设置为有条件的。
-
点击 2nd Condition Flow 的 + 菜单。
-
点击 添加条件。
-
从项目列表中选择 条件 - 身份验证级别。
-
点击 添加。
-
为 条件 - 身份验证级别 身份验证类型点击 必需,将其要求设置为必需。
-
点击 ⚙️(齿轮图标)。
-
输入
Level 2
作为别名。 -
为身份验证级别 (LoA) 输入
2
。 -
将最大有效期设置为 0。因此,当用户进行身份验证时,此级别仅对当前身份验证有效,而对任何后续 SSO 身份验证均无效。因此,当请求此级别时,用户始终需要再次使用此级别进行身份验证。
-
点击 保存
配置第二个身份验证级别的条件 -
点击 2nd Condition Flow 的 + 菜单。
-
点击 添加步骤。
-
从列表中选择 OTP 表单。
-
点击 添加。
-
为 OTP 表单 身份验证类型点击 必需,将其要求设置为必需。
最后,更改绑定。
-
点击屏幕顶部的 操作 菜单。
-
从列表中选择 绑定流程。
-
在下拉列表中选择 浏览器流程。
-
点击 保存。
要使用逐步提升机制,您需要在身份验证请求中指定请求的身份验证级别 (LoA)。claims
参数用于此目的
https://{DOMAIN}/realms/{REALMNAME}/protocol/openid-connect/auth?client_id={CLIENT-ID}&redirect_uri={REDIRECT-URI}&scope=openid&response_type=code&response_mode=query&nonce=exg16fxdjcu&claims=%7B%22id_token%22%3A%7B%22acr%22%3A%7B%22essential%22%3Atrue%2C%22values%22%3A%5B%22gold%22%5D%7D%7D%7D
claims
参数以 JSON 表示形式指定
claims= {
"id_token": {
"acr": {
"essential": true,
"values": ["gold"]
}
}
}
Keycloak javascript 适配器支持轻松构建此 JSON 并在登录请求中发送它。有关更多详细信息,请参阅 securing apps 部分中的 Keycloak JavaScript adapter。
您还可以使用更简单的参数 acr_values
而不是 claims
参数来请求特定级别作为非必要项。这在 OIDC 规范中有所提及。
您还可以为特定客户端配置默认级别,当参数 acr_values
或带有 acr
声明的 claims
参数不存在时,将使用该默认级别。有关更多详细信息,请参阅客户端 ACR 配置)。
要请求文本格式的 acr_values(例如 gold )而不是数字值,您可以配置 ACR 和 LoA 之间的映射。可以在 realm 级别(推荐)或客户端级别配置它。有关配置,请参阅ACR 到 LoA 映射。 |
有关更多详细信息,请参阅官方 OIDC 规范。
流程逻辑
先前配置的身份验证流程的逻辑如下
如果客户端请求高身份验证级别,即身份验证级别 2 (LoA 2),则用户必须执行完整的双因素身份验证:用户名/密码 + OTP。但是,如果用户已经在 Keycloak 中拥有会话,并且已使用用户名和密码(LoA 1)登录,则用户仅需提供第二个身份验证因素 (OTP)。
条件中的 Max Age 选项确定后续身份验证级别的有效时长(多少秒)。此设置有助于确定是否在后续身份验证期间再次要求用户出示身份验证因素。如果特定级别 X 由 claims
或 acr_values
参数请求,并且用户已经通过级别 X 身份验证,但该级别已过期(例如,最大年龄配置为 300 秒,用户在 310 秒之前进行了身份验证),则将要求用户使用该特定级别重新进行身份验证。但是,如果该级别尚未过期,则用户将被自动视为已通过该级别的身份验证。
将 Max Age 值设置为 0 意味着特定级别仅对本次身份验证有效。因此,每次请求该级别的重新身份验证都需要使用该级别再次进行身份验证。这对于应用程序中需要更高安全性的操作(例如,发送付款)并且始终需要使用特定级别进行身份验证的情况非常有用。
请注意,当登录请求从客户端通过用户浏览器发送到 Keycloak 时,URL 中的参数(例如 claims 或 acr_values )可能会被用户更改。如果客户端使用 PAR(推送授权请求)、请求对象或其他防止用户重写 URL 中参数的机制,则可以缓解这种情况。因此,在身份验证之后,建议客户端检查 ID Token 以仔细检查令牌中的 acr 是否与预期级别相符。 |
如果参数未显式请求级别,则 Keycloak 将要求使用身份验证流程中找到的第一个 LoA 条件进行身份验证,例如前面示例中的用户名/密码。当用户已经通过该级别身份验证并且该级别已过期时,用户不需要重新进行身份验证,但令牌中的 acr
值将为 0。此结果被视为仅基于 long-lived browser cookie
的身份验证,如 OIDC Core 1.0 规范的第 2 节中所述。
在用户的首次身份验证期间,始终执行第一个配置的带有 Conditional - Level Of Authentication 的子流程(无论请求的级别如何),因为用户尚没有任何级别。因此,我们建议第一个级别子流程包含用户身份验证所需的最低限度的身份验证器。此外,确保具有不同 Conditional - Level Of Authentication 值的子流程按从最低到最高的顺序排列,如上面的示例所示。例如,如果您配置了一个级别为 2 的子流程,然后添加了另一个级别为 1 的子流程,则在首次身份验证期间将始终询问级别为 2 的子流程,这可能不是期望的行为。 |
当管理员指定多个流程,为每个流程设置不同的 LoA 级别,并将这些流程分配给不同的客户端时,可能会出现冲突情况。但是,规则始终相同:如果用户具有某个级别,则只需要该级别即可连接到客户端。管理员有责任确保 LoA 是一致的。 |
具有身份验证级别条件的逐步身份验证适用于以下用例:每个级别都需要来自先前级别的所有身份验证方法。例如,级别 X 必须始终包含级别 X-1 所需的所有身份验证方法。对于特定级别(例如级别 3)需要与先前级别不同的身份验证方法的情况,使用 ACR 到特定流程的映射可能更合适。有关更多详细信息,请参阅使用客户端策略选择身份验证流程。 |
示例场景
-
级别 1 条件的最大年龄配置为 300 秒。
-
发送登录请求,未请求任何 acr。将使用级别 1,用户需要使用用户名和密码进行身份验证。令牌将具有
acr=1
。 -
在 100 秒后发送另一个登录请求。由于 SSO,用户已自动通过身份验证,令牌将返回
acr=1
。 -
在另外 201 秒后(自第 2 点中的身份验证起 301 秒)发送另一个登录请求。由于 SSO,用户已自动通过身份验证,但由于级别 1 被视为已过期,令牌将返回
acr=0
。 -
发送另一个登录请求,但现在它将在
claims
参数中显式请求级别 1 的 ACR。将要求用户使用用户名/密码重新进行身份验证,然后令牌中将返回acr=1
。
令牌中的 ACR 声明
ACR 声明由在 acr
客户端范围中定义的 acr loa level
协议映射器添加到令牌中。此客户端范围是 realm 默认客户端范围,因此将添加到 realm 中所有新创建的客户端。
如果您不希望令牌内部包含 acr
声明,或者您需要一些自定义逻辑来添加它,您可以从客户端中删除客户端范围。
请注意,当登录请求发起一个使用 claims
参数请求 acr
作为 essential
声明的请求时,Keycloak 将始终返回指定的级别之一。如果它无法返回指定的级别之一(例如,如果请求的级别未知或大于身份验证流程中配置的条件),则 Keycloak 将抛出错误。
客户端请求的注册或重置凭据
通常,当用户从客户端应用程序重定向到 Keycloak 时,会触发 browser
流程。如果 realm 注册已启用并且用户在登录屏幕上单击 Register
,则此流程可能允许用户注册。此外,如果为 realm 启用了忘记密码,则用户可以单击登录屏幕上的 Forget password
,这将触发 Reset credentials
流程,用户可以在电子邮件地址确认后重置凭据。
有时,客户端应用程序直接将用户重定向到 Registration 屏幕或 Reset credentials 流程可能很有用。结果操作将与用户在正常登录屏幕上单击 Register 或 Forget password 时的操作相匹配。可以按如下方式自动重定向到注册或重置凭据屏幕
-
当客户端希望用户直接重定向到注册时,OIDC 客户端应将参数
prompt=create
添加到登录请求。作为已弃用的替代方法,客户端可以将 OIDC 登录 URL 路径 (/auth
) 中的最后一个代码段替换为/registrations
。因此,完整的 URL 可能类似于以下内容:https://keycloak.example.com/realms/your_realm/protocol/openid-connect/registrations
。建议使用prompt=create
,因为它是一个规范标准。 -
当客户端希望用户直接重定向到
Reset credentials
流程时,OIDC 客户端应将 OIDC 登录 URL 路径 (/auth
) 中的最后一个代码段替换为/forgot-credentials
。
上述步骤是客户端直接请求注册或重置凭据流程的唯一受支持方法。出于安全目的,不支持且不建议客户端应用程序绕过 OIDC/SAML 流程并直接重定向到其他 Keycloak 端点(例如 /realms/realm_name/login-actions 或 /realms/realm_name/broker 下的端点)。 |
用户会话限制
可以配置用户可以拥有的会话数量的限制。会话可以按 realm 或按客户端进行限制。
要向流程添加会话限制,请执行以下步骤。
-
单击流程的 Add step。
-
从项目列表中选择 User session count limiter。
-
点击 添加。
-
对于 User Session Count Limiter 身份验证类型,单击 Required 以将其要求设置为必需。
-
单击 User Session Count Limiter 的 ⚙️ (齿轮图标)。
-
输入此配置的别名。
-
输入用户可以在此 realm 中拥有的最大会话数。例如,如果值为 2,则每个用户可以在此 realm 中拥有的最大 SSO 会话数为 2。如果值为 0,则禁用此检查。
-
输入用户可以为客户端拥有的最大会话数。例如,如果值为 2,则每个客户端在此 realm 中最多可以有 2 个 SSO 会话。因此,当用户尝试向客户端
foo
进行身份验证时,但该用户已向客户端foo
进行了 2 个 SSO 会话的身份验证,则将拒绝身份验证或根据配置的行为终止现有会话。如果使用值 0,则禁用此检查。如果同时启用了会话限制和客户端会话限制,则客户端会话限制始终低于会话限制是有意义的。每个客户端的限制永远不能超过此用户的所有 SSO 会话的限制。 -
选择当用户尝试在达到限制后创建会话时所需的行为。可用行为为
-
Deny new session - 当请求新会话且达到会话限制时,无法创建新会话。
-
Terminate oldest session - 当请求新会话且已达到会话限制时,将删除最旧的会话并创建新会话。
-
-
(可选)添加在达到限制时要显示的自定义错误消息。
请注意,用户会话限制应添加到您绑定的 Browser flow、Direct grant flow、Reset credentials 以及任何 Post broker login flow。身份验证器应在身份验证期间用户已知时添加(通常在身份验证流程结束时),并且通常应为 REQUIRED。请注意,在同一级别不可能同时具有 ALTERNATIVE 和 REQUIRED 执行。
对于大多数身份验证器(如 Direct grant flow
、Reset credentials
或 Post broker login flow
),建议在身份验证流程结束时将身份验证器添加为 REQUIRED。以下是 Reset credentials
流程的示例
对于 Browser
流程,请考虑不要在顶层流程中添加会话限制身份验证器。此建议是由于 Cookie
身份验证器,它基于 SSO cookie 自动重新验证用户身份。它位于顶层,最好不要在 SSO 重新身份验证期间检查会话限制,因为用户会话已经存在。因此,请考虑添加一个单独的 ALTERNATIVE 子流程,例如与 Cookie
处于同一级别的以下 authenticate-user-with-session-limit
示例。然后,您可以添加一个 REQUIRED 子流程,在以下 real-authentication-subflow
示例中,作为 authenticate-user-with-session-limit
的嵌套子流程,并在同一级别添加 User Session Limit
。在 real-authentication-subflow
内部,您可以以类似于默认浏览器流程的方式添加真正的身份验证器。以下示例流程允许用户使用身份提供程序或密码和 OTP 进行身份验证
关于 Post Broker login flow
,只要您没有在与身份提供程序进行身份验证后触发的其他身份验证器,您就可以在身份验证流程中添加 User Session Limits
作为唯一的身份验证器。但是,请确保此流程在您的身份提供程序中配置为 Post Broker Flow
。需要此要求,以便与身份提供程序的身份验证也参与会话限制。
目前,管理员负责维护不同配置之间的一致性。因此,请确保您的所有流程都使用相同的 User Session Limits 配置。 |
用户会话限制功能不适用于 CIBA。 |
Kerberos
Keycloak 支持通过简单且受保护的 GSSAPI 协商机制 (SPNEGO) 协议使用 Kerberos 票证登录。SPNEGO 在用户验证会话后通过 Web 浏览器透明地进行身份验证。对于非 Web 场景,或者当登录期间票证不可用时,Keycloak 支持使用 Kerberos 用户名和密码登录。
Web 身份验证的典型用例如下
-
用户登录到桌面。
-
用户使用浏览器访问由 Keycloak 保护的 Web 应用程序。
-
应用程序重定向到 Keycloak 登录。
-
Keycloak 渲染 HTML 登录屏幕,状态码为 401,HTTP 标头为
WWW-Authenticate: Negotiate
-
如果浏览器具有来自桌面登录的 Kerberos 票证,则浏览器在标头
Authorization: Negotiate 'spnego-token'
中将桌面登录信息传输到 Keycloak。否则,它将显示标准登录屏幕,用户输入登录凭据。 -
Keycloak 验证来自浏览器的令牌并验证用户身份。
-
如果将 LDAPFederationProvider 与 Kerberos 身份验证支持一起使用,Keycloak 会从 LDAP 预置用户数据。如果使用 KerberosFederationProvider,Keycloak 允许用户更新配置文件并预填充登录数据。
-
Keycloak 返回到应用程序。Keycloak 和应用程序通过 OpenID Connect 或 SAML 消息进行通信。Keycloak 充当 Kerberos/SPNEGO 登录的代理。因此,通过 Kerberos 进行身份验证的 Keycloak 对应用程序是隐藏的。
Negotiate www-authenticate 方案允许 NTLM 作为 Kerberos 的后备方案,并且在某些 Windows Web 浏览器中默认支持 NTLM。如果 www-authenticate 质询来自浏览器允许列表之外的服务器,则用户可能会遇到 NTLM 对话框提示。用户需要单击对话框上的“取消”按钮才能继续,因为 Keycloak 不支持此机制。如果 Intranet Web 浏览器未严格配置,或者 Keycloak 同时为 Intranet 和 Internet 用户提供服务,则可能会发生这种情况。可以使用自定义身份验证器将 Negotiate 质询限制为主机白名单。 |
执行以下步骤来设置 Kerberos 身份验证
-
Kerberos 服务器 (KDC) 的设置和配置。
-
Keycloak 服务器的设置和配置。
-
客户端机器的设置和配置。
Kerberos 服务器的设置
设置 Kerberos 服务器的步骤取决于操作系统 (OS) 和 Kerberos 供应商。有关设置和配置 Kerberos 服务器的说明,请参阅 Windows Active Directory、MIT Kerberos 和您的操作系统文档。
在设置期间,执行以下步骤
-
向您的 Kerberos 数据库添加一些用户主体。您还可以将 Kerberos 与 LDAP 集成,以便从 LDAP 服务器预置用户帐户。
-
为“HTTP”服务添加服务主体。例如,如果 Keycloak 服务器在
www.mydomain.org
上运行,则添加服务主体HTTP/www.mydomain.org@<kerberos realm>
。在 MIT Kerberos 上,您运行“kadmin”会话。在装有 MIT Kerberos 的机器上,您可以使用命令
sudo kadmin.local
然后,添加 HTTP 主体并使用如下命令将其密钥导出到 keytab 文件
addprinc -randkey HTTP/www.mydomain.org@MYDOMAIN.ORG
ktadd -k /tmp/http.keytab HTTP/www.mydomain.org@MYDOMAIN.ORG
确保 Keycloak 运行的主机可以访问 keytab 文件 /tmp/http.keytab
。
Keycloak 服务器的设置和配置
在您的机器上安装 Kerberos 客户端。
-
安装 Kerberos 客户端。如果您的机器运行 Fedora、Ubuntu 或 RHEL,请安装 freeipa-client 软件包,其中包含 Kerberos 客户端和其他实用程序。
-
配置 Kerberos 客户端(在 Linux 上,配置设置位于 /etc/krb5.conf 文件中)。
将您的 Kerberos realm 添加到配置中,并配置您的服务器运行的 HTTP 域。
例如,对于 MYDOMAIN.ORG realm,您可以像这样配置
domain_realm
部分[domain_realm] .mydomain.org = MYDOMAIN.ORG mydomain.org = MYDOMAIN.ORG
-
导出包含 HTTP 主体的 keytab 文件,并确保运行 Keycloak 服务器的进程可以访问该文件。对于生产环境,请确保只有此进程可以读取该文件。
对于上面的 MIT Kerberos 示例,我们将 keytab 导出到
/tmp/http.keytab
文件。如果您的密钥分发中心 (KDC) 和 Keycloak 在同一主机上运行,则该文件已可用。
启用 SPNEGO 处理
默认情况下,Keycloak 禁用 SPNEGO 协议支持。要启用它,请转到浏览器流并启用Kerberos。
将 Kerberos 要求从禁用设置为备选(Kerberos 是可选的)或必需(浏览器必须启用 Kerberos)。如果您尚未配置浏览器以使用 SPNEGO 或 Kerberos,则 Keycloak 将回退到常规登录屏幕。
配置 Kerberos 用户存储联合提供程序
您现在必须使用用户存储联合来配置 Keycloak 如何解释 Kerberos 票证。存在两个不同的具有 Kerberos 身份验证支持的联合提供程序。
要使用 LDAP 服务器支持的 Kerberos 进行身份验证,请配置 LDAP 联合提供程序。
-
转到 LDAP 提供程序的配置页面。
Ldap kerberos 集成 -
将允许 Kerberos 身份验证切换为开启
允许 Kerberos 身份验证使 Keycloak 使用 Kerberos 主体访问用户信息,以便信息可以导入到 Keycloak 环境中。
如果 LDAP 服务器不支持您的 Kerberos 解决方案,请使用 Kerberos 用户存储联合提供程序。
-
单击菜单中的 User Federation(用户联合)。
-
从添加提供程序选择框中选择 Kerberos。
Kerberos 用户存储提供程序
Kerberos 提供程序解析 Kerberos 票证以获取简单的主体信息,并将信息导入到本地 Keycloak 数据库。用户配置文件信息(如名字、姓氏和电子邮件)未预置。
客户端机器的设置和配置
客户端机器必须具有 Kerberos 客户端,并按照上述说明设置 krb5.conf
。客户端机器还必须在其浏览器中启用 SPNEGO 登录支持。如果您正在使用 Firefox 浏览器,请参阅配置 Firefox 以使用 Kerberos。
.mydomain.org
URI 必须在 network.negotiate-auth.trusted-uris
配置选项中。
在 Windows 域中,客户端无需调整其配置。Internet Explorer 和 Edge 已经可以参与 SPNEGO 身份验证。
凭据委派
Kerberos 支持凭据委派。应用程序可能需要访问 Kerberos 票证,以便它们可以重用它来与受 Kerberos 保护的其他服务进行交互。由于 Keycloak 服务器处理了 SPNEGO 协议,您必须在 OpenID Connect 令牌声明或 SAML 断言属性中将 GSS 凭据传播到您的应用程序。Keycloak 从 Keycloak 服务器将此传输到您的应用程序。要将此声明插入到令牌或断言中,每个应用程序都必须启用内置协议映射器 gss delegation credential
。此映射器在应用程序客户端页面的映射器选项卡中可用。有关更多详细信息,请参阅协议映射器章节。
应用程序必须反序列化它从 Keycloak 接收的声明,然后才能使用它对其他服务进行 GSS 调用。当您从访问令牌反序列化凭据到 GSSCredential 对象时,请创建 GSSContext,并将此凭据传递给 GSSManager.createContext
方法。例如
// Obtain accessToken in your application.
KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) servletReq.getUserPrincipal();
AccessToken accessToken = keycloakPrincipal.getKeycloakSecurityContext().getToken();
// Retrieve Kerberos credential from accessToken and deserialize it
String serializedGssCredential = (String) accessToken.getOtherClaims().
get(org.keycloak.common.constants.KerberosConstants.GSS_DELEGATION_CREDENTIAL);
GSSCredential deserializedGssCredential = org.keycloak.common.util.KerberosSerializationUtils.
deserializeCredential(serializedGssCredential);
// Create GSSContext to call other Kerberos-secured services
GSSContext context = gssManager.createContext(serviceName, krb5Oid,
deserializedGssCredential, GSSContext.DEFAULT_LIFETIME);
在 |
凭据委派具有安全隐患,因此仅在必要时且仅在 HTTPS 的情况下使用它。有关更多详细信息和示例,请参阅本文。 |
跨 realm 信任
在 Kerberos 协议中,realm
是一组 Kerberos 主体。这些主体的定义存在于 Kerberos 数据库中,该数据库通常是 LDAP 服务器。
Kerberos 协议允许跨 realm 信任。例如,如果存在 2 个 Kerberos realm A 和 B,则跨 realm 信任将允许 realm A 中的用户访问 realm B 的资源。Realm B 信任 realm A。
Keycloak 服务器支持跨 realm 信任。要实现此目的,请执行以下操作
-
为跨 realm 信任配置 Kerberos 服务器。实现此步骤取决于 Kerberos 服务器实现。此步骤对于将 Kerberos 主体
krbtgt/B@A
添加到 realm A 和 B 的 Kerberos 数据库是必要的。此主体在两个 Kerberos realm 上必须具有相同的密钥。主体在两个 realm 中必须具有相同的密码、密钥版本号和密码。有关更多详细信息,请参阅 Kerberos 服务器文档。
跨 realm 信任默认是单向的。您必须将主体 |
-
配置 Keycloak 服务器
-
当使用支持 Kerberos 的 LDAP 存储提供程序时,配置 realm B 的服务器主体,如本例所示:
HTTP/mydomain.com@B
。LDAP 服务器必须找到 realm A 中的用户(如果 realm A 中的用户要成功地向 Keycloak 进行身份验证),因为 Keycloak 必须执行 SPNEGO 流,然后找到用户。
-
查找用户基于 LDAP 存储提供程序选项 Kerberos principal attribute
。例如,如果将其配置为 userPrincipalName
之类的值,则在用户 john@A
的 SPNEGO 身份验证之后,Keycloak 将尝试查找属性 userPrincipalName
等于 john@A
的 LDAP 用户。如果 Kerberos principal attribute
留空,则 Keycloak 将基于其 Kerberos 主体的前缀(省略 realm)查找 LDAP 用户。例如,Kerberos 主体用户 john@A
必须在 LDAP 中以用户名 john
可用,因此通常在 LDAP DN 下,例如 uid=john,ou=People,dc=example,dc=com
。如果您希望 realm A 和 B 中的用户进行身份验证,请确保 LDAP 可以找到来自 realm A 和 B 的用户。
-
当使用 Kerberos 用户存储提供程序(通常,没有 LDAP 集成的 Kerberos)时,将服务器主体配置为
HTTP/mydomain.com@B
,并且来自 Kerberos realm A 和 B 的用户必须能够进行身份验证。
允许多个 Kerberos realm 中的用户进行身份验证,因为每个用户都将具有属性 KERBEROS_PRINCIPAL
,该属性引用用于身份验证的 Kerberos 主体,并且这用于进一步查找此用户。为避免当 Kerberos realm A
和 B
中都有用户 john
时发生冲突,Keycloak 用户的用户名可能包含 Kerberos realm(小写)。例如,用户名将是 john@a
。以防万一 realm 与配置的 Kerberos realm
匹配,realm 后缀可能会从生成的用户名中省略。例如,对于 Kerberos 主体 john@A
,用户名将是 john
,只要 Kerberos realm
在 Kerberos 提供程序上配置为 A
即可。
X.509 客户端证书用户身份验证
如果您已将服务器配置为使用 mutual SSL 身份验证,则 Keycloak 支持使用 X.509 客户端证书登录。
典型工作流程
-
客户端通过 SSL/TLS 通道发送身份验证请求。
-
在 SSL/TLS 握手期间,服务器和客户端交换其 x.509/v3 证书。
-
容器 (WildFly) 验证证书 PKIX 路径和证书到期日期。
-
x.509 客户端证书身份验证器通过使用以下方法来验证客户端证书
-
通过使用 CRL 或 CRL 分发点检查证书吊销状态。
-
通过使用 OCSP(在线证书状态协议)检查证书吊销状态。
-
验证证书中的密钥是否与预期密钥匹配。
-
验证证书中的扩展密钥是否与预期的扩展密钥匹配。
-
-
如果这些检查中的任何一项失败,则 x.509 身份验证失败。否则,身份验证器将提取证书身份并将其映射到现有用户。
当证书映射到现有用户时,行为会根据身份验证流而有所不同
-
在浏览器流中,服务器提示用户确认其身份或使用用户名和密码登录。
-
在直接授权流中,服务器登录用户。
请注意,验证证书 PKIX 路径是 Web 容器的责任。Keycloak 端的 X.509 身份验证器仅提供额外的支持来检查证书过期时间、证书吊销状态和密钥用途。如果您正在使用部署在反向代理后面的 Keycloak,请确保您的反向代理配置为验证 PKIX 路径。如果您不使用反向代理,并且用户直接访问 WildFly,那么您应该没问题,因为只要按照以下描述进行配置,WildFly 就会确保 PKIX 路径得到验证。 |
功能
支持的证书身份来源
-
使用正则表达式匹配 SubjectDN
-
X500 主题的电子邮件属性
-
来自主题备用名称扩展(RFC822Name 通用名称)的 X500 主题电子邮件
-
来自主题备用名称扩展的 X500 主题的其他名称。此其他名称通常是用户主体名称 (UPN)。
-
X500 主题的通用名称属性
-
使用正则表达式匹配颁发者 DN
-
证书序列号
-
证书序列号和颁发者 DN
-
SHA-256 证书指纹
-
PEM 格式的完整证书
正则表达式
Keycloak 通过使用正则表达式作为过滤器,从主题 DN 或颁发者 DN 中提取证书身份。例如,以下正则表达式匹配电子邮件属性
emailAddress=(.*?)(?:,|$)
如果将“身份来源
”设置为“使用正则表达式匹配 SubjectDN
”或“使用正则表达式匹配颁发者 DN
”,则应用正则表达式过滤。
将证书身份映射到现有用户
证书身份映射可以将提取的用户身份映射到现有用户的用户名、电子邮件或与证书身份匹配的自定义属性值。例如,将“身份来源
”设置为主题的电子邮件或将“用户映射方法
”设置为用户名或电子邮件,会使 X.509 客户端证书身份验证器使用证书主题 DN 中的电子邮件属性作为搜索条件,以便通过用户名或电子邮件搜索现有用户。
|
将 X.509 客户端证书身份验证添加到浏览器流程
-
点击菜单中的 身份验证。
-
单击浏览器流程。
-
从操作列表中,选择复制。
-
输入副本的名称。
-
单击复制。
-
点击 添加步骤。
-
单击“X509/验证用户名表单”。
-
点击 添加。
X509 执行 -
单击并将“X509/验证用户名表单”拖到“浏览器表单”执行之上。
-
将要求设置为“备选”。
X509 浏览器流程 -
单击操作菜单。
-
单击绑定流程。
-
从下拉列表中单击浏览器流程。
-
点击 保存。
X509 浏览器流程绑定
配置 X.509 客户端证书身份验证
- 用户身份来源
-
定义从客户端证书中提取用户身份的方法。
- 启用规范 DN 表示
-
定义是否使用规范格式来确定专有名称。官方 Java API 文档描述了该格式。此选项仅影响两个用户身份来源:使用正则表达式匹配 SubjectDN 和 使用正则表达式匹配颁发者 DN。当您设置新的 Keycloak 实例时,启用此选项。禁用此选项以保留与现有 Keycloak 实例的向后兼容性。
- 启用序列号十六进制表示
-
将 序列号表示为十六进制。符号位设置为 1 的序列号必须使用 00 八位字节进行左填充。例如,根据 RFC5280,十进制值161或十六进制表示形式a1的序列号编码为 00a1。有关更多详细信息,请参见 RFC5280,附录 B。
- 正则表达式
-
用作过滤器以提取证书身份的正则表达式。表达式必须包含单个组。
- 用户映射方法
-
定义将证书身份与现有用户匹配的方法。用户名或电子邮件通过用户名或电子邮件搜索现有用户。自定义属性映射器搜索具有与证书身份匹配的自定义属性的现有用户。自定义属性的名称是可配置的。
- 用户属性名称
-
其值与证书身份匹配的自定义属性。当属性映射与多个值相关时,请使用多个自定义属性。例如,“证书序列号和颁发者 DN”。
- 启用 CRL 检查
-
通过使用证书吊销列表检查证书的吊销状态。列表的位置在CRL 文件路径属性中定义。
- 启用 CRL 分发点以检查证书吊销状态
-
使用 CDP 检查证书吊销状态。大多数 PKI 机构在其证书中包含 CDP。
- CRL 文件路径
-
包含 CRL 列表的文件的路径。如果启用了启用 CRL 检查选项,则该值必须是有效文件的路径。
- CRL 如果未更新则中止
-
符合 RFC5280 的 CRL 包含一个下次更新字段,该字段指示将发布下一个 CRL 的日期。当该时间过去后,CRL 被认为已过时,应刷新。如果此选项为
true
,则如果 CRL 过时,身份验证将失败(推荐)。如果该选项设置为false
,则仍使用过时的 CRL 来验证用户证书。 - 启用 OCSP 检查
-
通过使用在线证书状态协议检查证书吊销状态。
- OCSP 故障开放行为
-
默认情况下,OCSP 检查必须返回肯定响应才能继续进行成功的身份验证。但是,有时此检查可能是不确定的:例如,OCSP 服务器可能无法访问、过载,或者客户端证书可能不包含 OCSP 响应者 URI。当此设置打开时,仅当 OCSP 响应者收到明确的否定响应并且证书确实被吊销时,才会拒绝身份验证。如果有效的 OCSP 响应不可用,则将接受身份验证尝试。
- OCSP 响应者 URI
-
覆盖证书中 OCSP 响应者 URI 的值。
- 验证密钥用途
-
验证是否设置了证书的 KeyUsage 扩展位。例如,“digitalSignature,KeyEncipherment”验证 KeyUsage 扩展中的位 0 和位 2 是否已设置。将此参数留空以禁用密钥用途验证。有关更多信息,请参见 RFC5280,第 4.2.1.3 节。当密钥用途不匹配时,Keycloak 会引发错误。
- 验证扩展密钥用途
-
验证扩展密钥用途扩展中定义的一个或多个用途。有关更多信息,请参见 RFC5280,第 4.2.1.12 节。将此参数留空以禁用扩展密钥用途验证。当颁发 CA 标记为关键且发生密钥用途扩展不匹配时,Keycloak 会引发错误。
- 验证证书策略
-
验证证书策略扩展中定义的一个或多个策略 OID。请参见 RFC5280,第 4.2.1.4 节。将参数留空以禁用证书策略验证。多个策略应使用逗号分隔。
- 证书策略验证模式
-
当在“
验证证书策略
”设置中指定多个策略时,它决定匹配应检查所有请求的策略都存在,还是一个匹配足以进行成功的身份验证。默认值为全部
,表示客户端证书中应存在所有请求的策略。 - 绕过身份确认
-
如果启用,X.509 客户端证书身份验证不会提示用户确认证书身份。Keycloak 在成功身份验证后让用户登录。
- 重新验证客户端证书
-
如果设置,客户端证书信任链将始终在应用程序级别使用配置的信任存储区中存在的证书进行验证。如果底层 Web 服务器不强制执行客户端证书链验证,例如因为它位于非验证负载均衡器或反向代理之后,或者当允许的 CA 数量对于相互 SSL 协商来说太大时(大多数浏览器将最大 SSL 协商数据包大小限制为 32767 字节,这大约对应于 200 个通告的 CA),这可能很有用。默认情况下,此选项处于关闭状态。
将 X.509 客户端证书身份验证添加到直接授权流程
-
点击菜单中的 身份验证。
-
从“操作列表”中选择复制以制作内置“直接授权”流程的副本。
-
输入副本的名称。
-
单击复制。
-
单击创建的流程。
-
单击“用户名验证”的垃圾桶图标 🗑️,然后单击删除。
-
单击“密码”的垃圾桶图标 🗑️,然后单击删除。
-
点击 添加步骤。
-
单击“X509/验证用户名”。
-
点击 添加。
X509 直接授权执行 -
按照 x509 浏览器流程 部分中描述的步骤设置 x509 身份验证配置。
-
单击绑定选项卡。
-
单击直接授权流程下拉列表。
-
单击新创建的“x509 直接授权”流程。
-
点击 保存。
X509 直接授权流程绑定
使用 CURL 的示例
以下示例演示如何使用直接授权流程为 realm test
中的用户获取访问令牌。该示例在 保护应用程序 部分中使用 OAuth2 资源所有者密码凭据授权和机密客户端 resource-owner
curl \
-d "client_id=resource-owner" \
-d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
-d "grant_type=password" \
--cacert /tmp/truststore.pem \
--cert /tmp/keystore.pem:kssecret \
"https://#:8543/realms/test/protocol/openid-connect/token"
文件 /tmp/truststore.pem
指向包含 Keycloak 服务器证书的信任存储区的文件。文件 /tmp/keystore.pem
包含与 Keycloak 用户对应的私钥和证书,该用户将通过此请求成功进行身份验证。这取决于身份验证器配置如何将证书中的内容映射到 Keycloak 用户,如 配置部分中所述。kssecret
可能是此密钥库文件的密码。
根据您的环境,可能需要使用更多 CURL 命令选项,例如
-
如果您使用自签名证书,则使用选项
--insecure
-
使用选项
--capath
以包含包含证书颁发机构路径的整个目录 -
如果您想使用与
PEM
不同的文件,则使用选项--cert-type
或--key-type
如果需要,请查阅 curl
工具的文档以获取详细信息。如果您使用 curl
以外的其他工具,请查阅您的工具的文档。但是,设置将是类似的。如果使用机密客户端,则需要包含密钥库和信任存储区以及客户端凭据。
如果可能,最好将 服务帐户 与 MTLS 客户端身份验证(客户端身份验证器 X509 证书 )结合使用,而不是使用带有 X.509 身份验证的直接授权,因为直接授权可能需要与客户端应用程序共享用户证书。使用服务帐户时,令牌是以客户端自身的名义获取的,这通常是更好、更安全的做法。 |
W3C Web 身份验证 (WebAuthn)
Keycloak 提供对 W3C Web 身份验证 (WebAuthn) 的支持。Keycloak 作为 WebAuthn 的 依赖方 (RP) 工作。
WebAuthn 的操作成功取决于用户的 WebAuthn 支持的身份验证器、浏览器和平台。请确保您的身份验证器、浏览器和平台支持 WebAuthn 规范。 |
WebAuthn 的规范使用 |
向浏览器流添加 WebAuthn 身份验证
-
点击菜单中的 身份验证。
-
单击浏览器流程。
-
从“Action list”中选择 Duplicate 以创建内置 Browser 流的副本。
-
输入 “WebAuthn Browser” 作为副本的名称。
-
单击复制。
-
单击名称以转到详细信息
-
单击 “WebAuthn Browser Browser - Conditional OTP” 的垃圾桶图标 🗑️,然后单击 Delete。
如果您需要所有用户都使用 WebAuthn
-
单击 **WebAuthn Browser Forms** 的 **+** 菜单。
-
点击 添加步骤。
-
单击 **WebAuthn Authenticator**。
-
点击 添加。
-
为 WebAuthn Authenticator 身份验证类型选择 Required,以将其要求设置为必需。
-
点击屏幕顶部的 操作 菜单。
-
从下拉列表中选择 Bind flow。
-
从下拉列表中选择 Browser。
-
点击 保存。
如果用户没有 WebAuthn 凭据,则用户必须注册 WebAuthn 凭据。 |
用户只能在注册了 WebAuthn 凭据后才能使用 WebAuthn 登录。因此,您可以不用添加 WebAuthn Authenticator 执行,而是
-
单击 **WebAuthn Browser Forms** 行的 **+** 菜单。
-
点击 添加子流程。
-
在 *name* 字段中输入 “Conditional 2FA”。
-
为 Conditional 2FA 选择 Conditional,以将其要求设置为有条件。
-
在 **Conditional 2FA** 行中,单击加号 + 并选择 **Add condition**。
-
点击 添加条件。
-
选择 **Condition - User Configured**。
-
点击 添加。
-
为 Condition - User Configured 选择 Required,以将其要求设置为必需。
-
将 WebAuthn Authenticator 拖放到 **Conditional 2FA** 流中
-
为 WebAuthn Authenticator 选择 Alternative,以将其要求设置为备选。
用户可以选择使用 WebAuthn 或 OTP 作为第二因素
-
在 **Conditional 2FA** 行中,单击加号 + 并选择 **Add step**。
-
从列表中选择 OTP 表单。
-
点击 添加。
-
为 **OTP Form** 选择 Alternative,以将其要求设置为备选。
使用 WebAuthn 身份验证器进行身份验证
注册 WebAuthn 身份验证器后,用户执行以下操作
-
打开登录表单。用户必须使用用户名和密码进行身份验证。
-
用户的浏览器会要求用户使用其 WebAuthn 身份验证器进行身份验证。
以管理员身份管理 WebAuthn
管理凭据
Keycloak 管理 WebAuthn 凭据的方式与其他凭据类似,请参阅 用户凭据管理
-
Keycloak 为用户分配一个必需的操作,以从 **Reset Actions** 列表中创建 WebAuthn 凭据,并选择 **Webauthn Register**。
-
管理员可以通过单击 **Delete** 来删除 WebAuthn 凭据。
-
管理员可以通过选择 **Show data…** 来查看凭据的数据,例如 AAGUID。
-
管理员可以通过在 **User Label** 字段中设置值并保存数据来为凭据设置标签。
管理策略
管理员可以为每个 realm 配置与 WebAuthn 相关的操作作为 **WebAuthn Policy**。
-
点击菜单中的 身份验证。
-
点击 策略 (Policy) 选项卡。
-
单击 **WebAuthn Policy** 选项卡。
-
配置策略中的项目(请参阅以下描述)。
-
点击 保存。
可配置的项目及其描述如下
配置 | 描述 |
---|---|
Relying Party 实体名称 |
作为 WebAuthn Relying Party 的可读服务器名称。此项为必填项,适用于 WebAuthn 身份验证器的注册。默认设置为 “keycloak”。有关更多详细信息,请参阅 WebAuthn 规范。 |
签名算法 |
告知 WebAuthn 身份验证器要用于 公钥凭据 的签名算法的算法。Keycloak 使用公钥凭据来签名和验证 身份验证断言。如果不存在算法,则采用默认的 ES256 和 RS256。ES256 和 RS256 是一个可选配置项,适用于 WebAuthn 身份验证器的注册。有关更多详细信息,请参阅 WebAuthn 规范。 |
Relying Party ID |
WebAuthn Relying Party 的 ID,它确定 公钥凭据 的范围。ID 必须是源的有效域。此 ID 是一个可选配置项,应用于 WebAuthn 身份验证器的注册。如果此条目为空,则 Keycloak 会采用 Keycloak 基本 URL 的主机部分。有关更多详细信息,请参阅 WebAuthn 规范。 |
证明传输偏好 |
浏览器上的 WebAuthn API 实现 (WebAuthn 客户端) 是生成证明语句的首选方法。此偏好是一个可选配置项,适用于 WebAuthn 身份验证器的注册。如果不存在选项,则其行为与选择 “none” 相同。有关更多详细信息,请参阅 WebAuthn 规范。 |
身份验证器附件 |
WebAuthn 身份验证器对于 WebAuthn 客户端的可接受附件模式。此模式是一个可选配置项,适用于 WebAuthn 身份验证器的注册。有关更多详细信息,请参阅 WebAuthn 规范。 |
要求可发现的凭据 |
要求 WebAuthn 身份验证器将公钥凭据生成为 客户端可发现的凭据 的选项。此选项适用于 WebAuthn 身份验证器的注册。如果留空,则其行为与选择 “No” 相同。有关更多详细信息,请参阅 WebAuthn 规范。 |
用户验证要求 |
要求 WebAuthn 身份验证器确认用户验证的选项。这是一个可选配置项,适用于 WebAuthn 身份验证器的注册以及用户通过 WebAuthn 身份验证器的身份验证。如果不存在选项,则其行为与选择 “preferred” 相同。有关更多详细信息,请参阅 用于注册 WebAuthn 身份验证器的 WebAuthn 规范 和 用于通过 WebAuthn 身份验证器验证用户的 WebAuthn 规范。 |
超时 |
注册 WebAuthn 身份验证器和使用 WebAuthn 身份验证器验证用户的超时值(以秒为单位)。如果设置为零,则其行为取决于 WebAuthn 身份验证器的实现。默认值为 0。有关更多详细信息,请参阅 用于注册 WebAuthn 身份验证器的 WebAuthn 规范 和 用于通过 WebAuthn 身份验证器验证用户的 WebAuthn 规范。 |
避免相同身份验证器注册 |
如果启用,Keycloak 无法重新注册已注册的 WebAuthn 身份验证器。 |
可接受的 AAGUID |
WebAuthn 身份验证器必须针对其注册的 AAGUID 白名单。 |
证明语句验证
注册 WebAuthn 身份验证器时,Keycloak 会验证 WebAuthn 身份验证器生成的证明语句的可信度。Keycloak 要求将信任锚的证书导入到 信任库 中。
要省略此验证,请禁用此信任库或将 WebAuthn 策略的配置项 “Attestation Conveyance Preference” 设置为 “none”。
以用户身份管理 WebAuthn 凭据
无密码 WebAuthn 与双因素身份验证结合使用
Keycloak 使用 WebAuthn 进行双因素身份验证,但您可以将 WebAuthn 用作第一因素身份验证。在这种情况下,具有 passwordless
WebAuthn 凭据的用户无需密码即可向 Keycloak 进行身份验证。在 realm 和单个身份验证流的上下文中,Keycloak 可以将 WebAuthn 用作无密码和双因素身份验证机制。
管理员通常要求用户为 WebAuthn 无密码身份验证注册的 Passkey 满足不同的要求。例如,Passkey 可能要求用户使用 PIN 码向 Passkey 进行身份验证,或者 Passkey 使用更强的证书颁发机构进行证明。
因此,Keycloak 允许管理员配置单独的 WebAuthn Passwordless Policy
。存在类型为必需的 Webauthn Register Passwordless
操作和类型为 WebAuthn Passwordless Authenticator
的单独身份验证器。
设置
按照以下步骤设置 WebAuthn 无密码支持
-
(如果尚不存在)注册一个新的必需操作以支持 WebAuthn 无密码。使用 启用 WebAuthn 身份验证器注册 中描述的步骤。注册
Webauthn Register Passwordless
操作。 -
配置策略。您可以使用 管理策略 中描述的步骤和配置选项。在管理控制台的 **WebAuthn Passwordless Policy** 选项卡中执行配置。通常,Passkey 的要求将比双因素策略的要求更高。例如,在配置无密码策略时,您可以将 **User Verification Requirement** 设置为 **Required**。
-
配置身份验证流。使用 向浏览器流添加 WebAuthn 身份验证 中描述的 **WebAuthn Browser** 流。按如下方式配置流
-
**WebAuthn Browser Forms** 子流包含 **Username Form** 作为第一个身份验证器。删除默认的 **Username Password Form** 身份验证器,并添加 **Username Form** 身份验证器。此操作要求用户提供用户名作为第一步。
-
将会有一个必需的子流,例如可以命名为 **Passwordless Or Two-factor**。此子流指示用户可以使用无密码 WebAuthn 凭据或双因素身份验证进行身份验证。
-
该流包含 **WebAuthn Passwordless Authenticator** 作为第一个备选项。
-
第二个备选项将是一个名为 **Password And Two-factor Webauthn** 的子流,例如。此子流包含 **Password Form** 和 **WebAuthn Authenticator**。
-
流的最终配置类似于此
现在,您可以将 **WebAuthn Register Passwordless** 作为必需操作添加到 Keycloak 中已知的用户,以进行测试。在首次身份验证期间,用户必须使用密码和第二因素 WebAuthn 凭据。如果用户使用 WebAuthn 无密码凭据,则无需提供密码和第二因素 WebAuthn 凭据。
无登录 WebAuthn
Keycloak 使用 WebAuthn 进行双因素身份验证,但您可以将 WebAuthn 用作第一因素身份验证。在这种情况下,具有 passwordless
WebAuthn 凭据的用户无需提交登录名或密码即可向 Keycloak 进行身份验证。在 realm 的上下文中,Keycloak 可以将 WebAuthn 用作无登录/无密码和双因素身份验证机制。
管理员通常要求用户为 WebAuthn 无登录身份验证注册的 Passkey 满足不同的要求。无登录身份验证要求用户向 Passkey 进行身份验证(例如,使用 PIN 码或指纹),并且与无登录凭据关联的加密密钥物理存储在 Passkey 上。并非所有 Passkey 都满足这种要求。请咨询您的 Passkey 供应商,以了解您的设备是否支持“用户验证”和“可发现的凭据”。请参阅 受支持的 Passkey。
Keycloak 允许管理员以允许无登录身份验证的方式配置 WebAuthn Passwordless Policy
。请注意,无登录身份验证只能通过 WebAuthn Passwordless Policy
和 WebAuthn Passwordless
凭据进行配置。WebAuthn 无登录身份验证和 WebAuthn 无密码身份验证可以在同一 realm 上配置,但将共享相同的策略 WebAuthn Passwordless Policy
。
设置
按照以下步骤设置 WebAuthn 无登录支持
-
(如果尚不存在)注册一个新的必需操作以支持 WebAuthn 无密码。使用 启用 WebAuthn 身份验证器注册 中描述的步骤。注册
Webauthn Register Passwordless
操作。 -
配置
WebAuthn Passwordless Policy
。在管理控制台的Authentication
部分中的Policies
→WebAuthn Passwordless Policy
选项卡中执行配置。当您为无登录场景配置策略时,必须将 **User Verification Requirement** 设置为 **required**,并将 **Require Discoverable Credential** 设置为 **Yes**。请注意,由于没有专门的无登录策略,因此无法将用户验证=否/可发现凭据=否的身份验证场景与无登录场景(用户验证=是/可发现凭据=是)混合使用。Passkey 上的存储容量通常非常有限,这意味着您无法在 Passkey 上存储许多可发现的凭据。 -
配置身份验证流。创建一个新的身份验证流,添加 “WebAuthn Passwordless” 执行,并将执行的 Requirement 设置设置为 **Required**
流的最终配置类似于此
现在,您可以将必需的操作 WebAuthn Register Passwordless
添加到 Keycloak 中已知的用户,以进行测试。配置了必需操作的用户将必须进行身份验证(例如,使用用户名/密码),然后系统将提示他们注册一个 Passkey,用于无登录身份验证。
供应商特定备注
兼容性检查清单
与 Keycloak 进行无登录身份验证需要 Passkey 满足以下功能
-
FIDO2 兼容性:不要与 FIDO/U2F 混淆
-
用户验证:Passkey 验证用户的能力(防止有人找到您的 Passkey 并能够进行无登录和无密码身份验证)
-
可发现的凭据:Passkey 存储登录名和与客户端应用程序关联的加密密钥的能力
Passkeys
Keycloak 提供了对 Passkeys 的预览支持。Keycloak 充当 Passkeys 依赖方 (RP)。
Passkey 注册和身份验证通过 WebAuthn 的功能实现。因此,Keycloak 的用户可以通过现有的 WebAuthn 注册和身份验证 来进行 Passkey 注册和身份验证。
同步 Passkeys 和设备绑定 Passkeys 都可以用于同设备和跨设备身份验证 (CDA)。但是,Passkeys 操作的成功与否取决于用户的环境。请确保在 该环境 中哪些操作可以成功。 |
使用条件 UI 的 Passkey 身份验证
使用条件 UI 的 Passkey 身份验证可以像 LoginLess WebAuthn 中一样,使用用户的 passkey 进行身份验证。此身份验证会向用户显示设备上存储的 passkey 列表,用户在该设备上运行浏览器。因此,用户可以选择列表中的一个 passkey 来进行身份验证。与 LoginLess WebAuthn 相比,此身份验证改善了用户的身份验证体验。
此身份验证使用 WebAuthn 条件 UI。因此,此身份验证的成功与否取决于用户的环境。如果环境不支持 WebAuthn 条件 UI,则此身份验证将回退到 LoginLess WebAuthn。 |
Passkey 身份验证是 预览版,尚未完全支持。此功能默认情况下处于禁用状态。 要启用,请使用 |
设置
按如下步骤设置使用条件 UI 的 Passkey 身份验证
-
(如果尚不存在)注册一个新的必需操作以支持 WebAuthn 无密码。使用 启用 WebAuthn 身份验证器注册 中描述的步骤。注册
Webauthn Register Passwordless
操作。 -
配置
WebAuthn Passwordless Policy
。在管理控制台的Authentication
部分,在Policies
→WebAuthn Passwordless Policy
选项卡中执行配置。当您为无密码登录场景配置策略时,将 User Verification Requirement 设置为 required,并将 Require discoverable credential 设置为 Yes。请注意,由于没有专门的无密码登录策略,因此无法混合使用用户验证=否/可发现凭据=否 的身份验证场景和无密码登录场景(用户验证=是/可发现凭据=是)。硬件 passkey 上的存储容量通常非常有限,这意味着您无法在您的 passkey 上存储许多可发现的凭据。但是,如果您使用由 Google 帐户支持的 Android 手机作为 passkey 设备或由 Bitwarden 支持的 iPhone,则此限制可能会得到缓解。 -
配置身份验证流。创建一个新的身份验证流,添加 Passkeys Conditional UI Authenticator 执行,并将执行的 Requirement 设置设置为 Required。
流的最终配置看起来类似于这样:
-
在 realm 中将上述流绑定为 browser 身份验证流,如上面的 WebAuthn 部分 中所述。
上面的身份验证流要求用户必须在其帐户上已拥有 passkey 凭据才能登录。此要求意味着 realm 中的所有用户都必须已设置 passkey。例如,可以通过启用用户注册来实现,如下所述。
设置用于 passkeys 条件 UI 的注册
注册流设置的替代方法是将所需的 action WebAuthn Register Passwordless
添加到 Keycloak 已知的用户。配置了所需操作的用户将必须进行身份验证(例如,使用用户名/密码),然后将被提示注册一个 passkey,用于无密码登录身份验证。
我们计划改进可用性,并允许将条件 passkey 与现有的身份验证器和表单(例如默认的用户名/密码表单)集成。 |
从 Web Authn Level 3 开始,Resident Key 被 Discoverable Credential 取代。 |
如果用户的浏览器支持 WebAuthn 条件 UI,则会显示以下屏幕。
当用户单击 Select your passkey 文本框时,将显示用户在其上运行浏览器的设备上存储的 passkey 列表,如下所示。
如果用户的浏览器不支持 WebAuthn 条件 UI,则身份验证将回退到 LoginLess WebAuthn,如下所示。
恢复代码
恢复代码是由 Keycloak 自动生成的多个顺序一次性密码(目前为 12 个)。这些代码可以用作第二因素身份验证 (2FA),方法是将 Recovery Authentication Code Form
验证器添加到您的身份验证流程中。在流程中配置后,Keycloak 会要求用户输入顺序中的下一个生成的代码。当用户输入当前代码后,该代码将被删除,并且下次登录时将需要下一个代码。
由于其性质,恢复代码通常用作另一种 2FA 方法的备份。它们可以补充 OTP Form
或 WebAuthn Authenticator
,为登录 Keycloak 提供一种备用方法,例如,如果用于先前 2FA 方法的软件或硬件设备损坏或不可用。
RecoveryCodes 是 预览版,尚未完全支持。此功能默认情况下处于禁用状态。 要启用,请使用 |
启用恢复代码所需操作
检查是否在 Keycloak 中启用了恢复代码操作
-
点击菜单中的 身份验证。
-
点击 Required Actions(必需的操作) 选项卡。
-
确保 Recovery Authentication Codes 开关 Enabled 设置为 On。
如果您希望所有新用户在首次登录时注册其恢复代码凭据,请将 Default Action 开关切换为 On。
将恢复代码添加到浏览器流
以下过程将 Recovery Authentication Code Form
添加为默认 Browser 流中的另一种登录方式。
-
在 realm 菜单中单击 Authentication。
-
单击浏览器流程。
-
从 Action list 中选择 Duplicate 以创建内置 Browser 流的副本。
例如,输入 Recovery Codes Browser 作为副本的名称。
-
单击复制。
-
在流 Recovery Codes Browser Browser - Conditional OTP 中,单击 Add (+) 按钮,然后选择 Add Execution。
-
筛选以查找 Recovery Authentication Code Form 并 Add 执行。
-
将新步骤的 requirement 设置为 Alternative。
-
也将 OTP Form 的 requirement 设置为 Alternative。
恢复代码浏览器流 -
点击屏幕顶部的 操作 菜单。
-
从下拉列表中选择 Bind flow。
-
从下拉列表中选择 Browser flow,以将此新流设置为 realm 的默认流。
-
点击 保存。
通过此配置,两种 2FA 身份验证器(OTP Form
和 Recovery Authentication Code Form
)都是登录 Keycloak 的备用方式。如果用户配置了两种凭据类型,则默认情况下将显示 OTP Form
,但另一个选项 Try Another Way 将可用,允许选择 Recovery Authentication Code 进行登录。
您可以在 2FA 条件工作流示例 中查看更多 2FA 配置示例。
创建恢复代码凭据
一旦启用恢复代码所需操作并且在流中管理了凭据类型,用户就可以请求创建自己的代码。该操作只是另一个 所需操作,可以在 Keycloak 中使用(直接由用户使用帐户控制台调用,或由管理员使用管理控制台分配)。
所需操作在执行时,会生成代码列表并将其呈现给用户。该操作提供打印、下载或复制代码列表的功能,以帮助用户将其存储在安全的地方。为了完成设置,应预先选中复选框 I have saved these codes somewhere safe。
可以随时重新创建恢复代码。
条件流中的条件
正如 执行要求 中提到的,Condition 执行只能包含在 Conditional 子流中。如果所有 Condition 执行都评估为 true,则 Conditional 子流充当 Required。您可以处理 Conditional 子流中的下一个执行。如果 Conditional 子流中包含的某些执行评估为 false,则整个子流将被视为 Disabled。
可用条件
条件 - 用户角色
-
此执行能够确定用户是否具有由 User role 字段定义的角色。如果用户具有所需的角色,则该执行被视为 true,并评估其他执行。管理员必须定义以下字段
- 别名
-
描述执行的名称,该名称将显示在身份验证流中。
- 用户角色
-
用户应具有的角色才能执行此流程。要指定应用程序角色,语法为
appname.approle
(例如myapp.myrole
)。
条件 - 用户已配置
-
这检查是否为用户配置了流中的其他执行。“执行要求”部分包含 OTP 表单的示例。
条件 - 用户属性
-
这检查用户是否设置了所需的属性:可选地,检查还可以评估组属性。可以否定输出,这意味着用户不应具有该属性。用户属性 部分显示了如何添加自定义属性。您可以提供以下字段
- 别名
-
描述执行的名称,该名称将显示在身份验证流中。
- 属性名称
-
要检查的属性的名称。
- 预期属性值
-
属性中的预期值。
- 包括组属性
-
如果为“开”,则条件检查任何加入的组是否具有一个属性与配置的名称和值匹配:此选项可能会影响性能
- 否定输出
-
您可以否定输出。换句话说,该属性不应存在。
条件 - 子流已执行
-
该条件检查先前的子流是否在身份验证过程中成功执行(或未执行)。因此,流可以根据先前子流的终止来触发其他步骤。存在以下配置字段
- 流名称
-
要检查是否已执行或未执行的子流名称。必需。
- 检查结果
-
条件何时评估为 true。如果
executed
在配置的子流以输出成功执行时返回 true,否则返回 false。如果not-executed
在子流以输出成功执行时返回 false,否则返回 true(前一个选项的否定)。
条件 - 客户端范围
-
该条件评估配置的客户端范围是否作为请求身份验证的客户端的客户端范围存在。存在以下配置字段
- 客户端范围名称
-
客户端范围的名称,该名称应作为正在请求身份验证的客户端的客户端范围存在。如果请求的客户端范围是正在请求登录的客户端的默认客户端范围,则条件将评估为 true。如果请求的客户端范围是正在请求登录的客户端的可选客户端范围,则如果客户端在登录请求中发送了客户端范围(例如,在 OIDC/OAuth2 客户端登录的情况下通过
scope
参数),则条件将评估为 true。必需。 - 否定输出
-
对检查结果应用 NOT。当此项为 true 时,则仅当配置的客户端范围不存在时,条件才会评估为 true。
在条件流中显式拒绝/允许访问
您可以在条件流中允许或拒绝访问资源。两个身份验证器 Deny Access
和 Allow Access
通过条件控制对资源的访问。
允许访问
-
身份验证器将始终成功进行身份验证。此身份验证器不可配置。
拒绝访问
-
访问将始终被拒绝。您可以定义一条错误消息,该消息将显示给用户。您可以提供以下字段
- 别名
-
描述执行的名称,该名称将显示在身份验证流中。
- 错误消息
-
将向用户显示的错误消息。错误消息可以作为特定消息提供,也可以作为属性提供,以便将其用于本地化。(例如,“您没有 'admin' 角色。”,消息属性中的 my-property-deny)留空则使用定义为属性
access-denied
的默认消息。
这是一个示例,说明如何拒绝没有 role1
角色的所有用户的访问,并显示由属性 deny-role1
定义的错误消息。此示例包括 Condition - User Role
和 Deny Access
执行。
Deny Access
的配置非常简单。您可以像这样指定任意别名和所需的消息最后一件事情是在登录主题 messages_en.properties
(对于英语)中定义带有错误消息的属性
deny-role1 = You do not have required role!
2FA 条件工作流示例
本节介绍了一些条件工作流的示例,这些示例以不同的方式集成了第二因素身份验证 (2FA)。这些示例复制了默认的 browser
流,并修改了 forms
子流中的配置。
条件 2FA 子流
默认的 browser
流使用 Conditional OTP
子流,该子流已经提供了带有 OTP 表单(一次性密码)的 2FA。遵循相同的思路,不同的 2FA 方法可以与 Condition - User Configured
集成。
forms
子流包含另一个带有 Condition - user configured
的 2FA
条件子流。三个 2FA 步骤(OTP、Webauthn 和恢复代码)被允许作为备选项。如果为用户配置了这三个选项,用户将能够选择其中一个。由于子流是条件性的,因此如果未配置 2FA 凭据,则身份验证过程将成功完成。
身份验证会话
当在 Web 浏览器中首次打开登录页面时,Keycloak 会创建一个名为身份验证会话的对象,该对象存储有关请求的一些有用信息。每当在同一浏览器中的不同选项卡中打开新的登录页面时,Keycloak 都会创建一个名为身份验证子会话的新记录,该记录存储在身份验证会话中。身份验证请求可以来自任何类型的客户端,例如 Admin CLI。在这种情况下,也会创建一个新的身份验证会话,其中包含一个身份验证子会话。请注意,身份验证会话也可以通过浏览器流以外的其他方式创建。
身份验证会话通常在 30 分钟后过期(默认)。确切时间由管理控制台的 Sessions 选项卡中的 登录超时 开关指定,在配置 realm 时设置。
在更多浏览器选项卡中进行身份验证
如上一节所述,情况可能涉及尝试从单个浏览器的多个选项卡向 Keycloak 服务器进行身份验证的用户。但是,当该用户在一个浏览器选项卡中进行身份验证时,其他浏览器选项卡将自动重启身份验证。此身份验证的发生是由于 Keycloak 登录页面上提供的小型 javascript。重启通常会在其他浏览器选项卡中对用户进行身份验证,并重定向到客户端,因为现在存在 SSO 会话,这是因为用户刚刚在第一个浏览器选项卡中成功通过身份验证。当用户未在其他浏览器选项卡中自动进行身份验证时,存在一些罕见的例外情况,例如当使用 OIDC 参数 prompt=login 或 step-up authentication 请求比当前已验证的因素更强的身份验证因素时。
在某些罕见情况下,可能会发生这种情况:在第一个浏览器选项卡中进行身份验证后,其他浏览器选项卡无法重启身份验证,因为身份验证会话已过期。在这种情况下,特定的浏览器选项卡将以协议特定的方式将有关身份验证会话过期的错误重定向回客户端。有关更多详细信息,请参阅 securing apps 部分中 OIDC 文档 的相应章节。当客户端应用程序收到此类错误时,它可以立即重新提交 OIDC/SAML 身份验证请求到 Keycloak,因为这通常应由于如前所述的现有 SSO 会话而自动对用户进行身份验证。因此,最终用户将在所有浏览器选项卡中自动进行身份验证。securing apps 部分中的 Keycloak JavaScript 适配器 和 Keycloak 身份提供程序 支持自动处理此错误,并在这种情况下重试对 Keycloak 服务器的身份验证。
集成身份提供程序
身份代理是一个中介服务,用于连接服务提供商和身份提供商。身份代理与外部身份提供商建立关系,以使用提供商的身份来访问服务提供商公开的内部服务。
从用户的角度来看,身份代理提供了一种以用户为中心、集中化的方式来管理安全域和 realm 的身份。您可以将帐户与来自身份提供商的一个或多个身份链接起来,或者根据来自身份提供商的身份信息创建帐户。
身份提供商源自用于对用户进行身份验证并向用户发送身份验证和授权信息的特定协议。它可以是
-
社交提供商,例如 Facebook、Google 或 Twitter。
-
需要访问您服务的业务合作伙伴。
-
您想要集成的基于云的身份服务。
通常,Keycloak 基于以下协议来构建身份提供商
-
SAML v2.0
-
OpenID Connect v1.0
-
OAuth v2.0
代理概述
当使用 Keycloak 作为身份代理时,Keycloak 不会强制用户提供凭据以在特定 realm 中进行身份验证。Keycloak 显示身份提供商列表,用户可以从中进行身份验证。
如果您配置了默认身份提供商,Keycloak 会将用户重定向到默认提供商。
不同的协议可能需要不同的身份验证流程。Keycloak 支持的所有身份提供商都使用以下流程。 |
-
未经身份验证的用户在客户端应用程序中请求受保护的资源。
-
客户端应用程序将用户重定向到 Keycloak 进行身份验证。
-
Keycloak 显示登录页面,其中包含在 realm 中配置的身份提供商列表。
-
用户通过单击其按钮或链接来选择其中一个身份提供商。
-
Keycloak 向目标身份提供商发出身份验证请求,请求身份验证,并将用户重定向到身份提供商的登录页面。管理员已为管理控制台的身份提供商设置了连接属性和其他配置选项。
-
用户提供凭据或同意通过身份提供商进行身份验证。
-
在身份提供商成功进行身份验证后,用户会重定向回 Keycloak 并收到身份验证响应。通常,响应包含一个安全令牌,Keycloak 使用该令牌来信任身份提供商的身份验证并检索用户信息。
-
Keycloak 检查来自身份提供商的响应是否有效。如果有效,Keycloak 会导入并创建一个用户(如果该用户尚不存在)。如果令牌不包含该信息,Keycloak 可能会向身份提供商请求更多用户信息。此行为称为身份联合。如果用户已存在,Keycloak 可能会要求用户将从身份提供商返回的身份与现有帐户链接起来。此行为称为帐户链接。使用 Keycloak,您可以配置帐户链接,并在首次登录流程中指定它。在此步骤中,Keycloak 对用户进行身份验证,并颁发其令牌以访问服务提供商中请求的资源。
-
当用户通过身份验证后,Keycloak 会通过发送先前在本地身份验证期间颁发的令牌,将用户重定向到服务提供商。
-
服务提供商从 Keycloak 接收令牌,并允许访问受保护的资源。
此流程可能存在变体。例如,客户端应用程序可以请求特定的身份提供商,而不是显示身份提供商列表,或者您可以将 Keycloak 设置为强制用户在联合其身份之前提供其他信息。
在身份验证过程结束时,Keycloak 会向客户端应用程序颁发其令牌。客户端应用程序与外部身份提供商是分离的,因此它们看不到客户端应用程序的协议或它们如何验证用户的身份。提供商只需要了解 Keycloak。
默认身份提供商
Keycloak 可以重定向到身份提供商,而不是显示登录表单。要启用此重定向
-
点击菜单中的 身份验证。
-
单击浏览器流程。
-
单击 身份提供商重定向器 行上的齿轮图标 ⚙️。
-
将 默认身份提供商 设置为您要将用户重定向到的身份提供商。
如果 Keycloak 找不到配置的默认身份提供商,则会显示登录表单。
此身份验证器负责处理 kc_idp_hint
查询参数。有关更多信息,请参阅 客户端建议的身份提供商 部分。
身份验证器将重定向到身份提供商,并且身份验证将委派给身份提供商。在与身份提供商的登录成功完成后,browser 身份验证流程将不会继续。如果您想在身份提供商登录后执行其他步骤(例如,双因素身份验证),则可能需要配置 登录后流程。 |
常规配置
身份代理配置的基础是身份提供商 (IDP)。Keycloak 为每个 realm 创建身份提供商,并默认对每个应用程序启用它们。来自 realm 的用户在登录应用程序时可以使用任何已注册的身份提供商。
-
单击菜单中的 身份提供商。
身份提供商 -
选择一个身份提供商。Keycloak 显示您选择的身份提供商的配置页面。
添加 Facebook 身份提供商当您配置身份提供商时,身份提供商会作为选项显示在 Keycloak 登录页面上。您可以为每个身份提供商在登录屏幕上放置自定义图标。有关更多信息,请参阅 自定义图标。
IDP 登录页面- 社交
-
社交提供商在您的 realm 中启用社交身份验证。借助 Keycloak,用户可以使用社交网络帐户登录您的应用程序。支持的提供商包括 Twitter、Facebook、Google、LinkedIn、Instagram、Microsoft、PayPal、Openshift v4、GitHub、GitLab、Bitbucket 和 Stack Overflow。
- 基于协议
-
基于协议的提供商依赖于特定协议来对用户进行身份验证和授权。使用这些提供商,您可以连接到任何符合特定协议的身份提供商。Keycloak 提供对 SAML v2.0 和 OpenID Connect v1.0 协议的支持。您可以配置和代理基于这些开放标准的任何身份提供商。
尽管每种身份提供商都有其配置选项,但所有身份提供商都共享一个通用配置。以下是可用的配置选项
配置 | 描述 |
---|---|
别名 |
别名是身份提供商的唯一标识符,并引用内部身份提供商。Keycloak 使用别名来构建 OpenID Connect 协议的重定向 URI,这些协议需要重定向 URI 或回调 URL 才能与身份提供商通信。所有身份提供商都必须具有别名。别名示例包括 |
已启用 |
切换提供商的开启或关闭状态。 |
在登录页面隐藏 |
当开启时,Keycloak 不会在登录页面上将此提供商显示为登录选项。客户端可以使用 URL 中的“kc_idp_hint”参数请求此提供商以进行登录。 |
仅账户链接 |
当开启时,Keycloak 会将现有账户与此提供商链接。此提供商无法让用户登录,并且 Keycloak 不会在登录页面上将此提供商显示为选项。 |
存储令牌 |
当开启时,Keycloak 会存储来自身份提供商的令牌。 |
已存储令牌可读 |
当开启时,用户可以检索已存储的身份提供商令牌。此操作也适用于代理客户端级别的角色读取令牌。 |
信任电子邮件 |
当开启时,Keycloak 信任来自身份提供商的电子邮件地址。如果 realm 需要电子邮件验证,则从此身份提供商登录的用户无需执行电子邮件验证过程。 |
GUI 顺序 |
登录页面上可用身份提供商的排序顺序。 |
验证必要声明 |
当开启时,身份提供商颁发的 ID 令牌必须具有特定的声明,否则用户无法通过此代理进行身份验证 |
必要声明 |
当验证必要声明为开启时,要过滤的 JWT 令牌声明的名称(匹配区分大小写) |
必要声明值 |
当验证必要声明为开启时,要匹配的 JWT 令牌声明的值(支持正则表达式格式) |
首次登录流程 |
当用户首次使用此身份提供商登录 Keycloak 时,Keycloak 触发的身份验证流程。 |
登录后流程 |
当用户完成使用外部身份提供商登录后,Keycloak 触发的身份验证流程。 |
同步模式 |
通过映射器更新来自身份提供商的用户信息的策略。当选择 legacy 时,Keycloak 使用当前行为。Import 不更新用户数据,而 force 在可能的情况下更新用户数据。有关更多信息,请参阅 身份提供商映射器。 |
用户名区分大小写 |
如果启用,则在联合用户时,来自身份提供商的原始用户名将保持原样。否则,来自身份提供商的用户名将转换为小写,如果区分大小写,则可能与原始值不匹配。此设置仅影响与联合身份关联的用户名,因为服务器中的用户名始终为小写。 |
社交身份提供商
社交身份提供商可以将身份验证委托给受信任、受尊重的社交媒体帐户。Keycloak 包括对社交网络的支持,例如 Google、Facebook、Twitter、GitHub、LinkedIn、Microsoft 和 Stack Overflow。
Bitbucket
要使用 Bitbucket 登录,请执行以下步骤。
-
单击菜单中的 身份提供商。
-
从添加提供商列表中,选择 Bitbucket。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器选项卡中,执行 Bitbucket Cloud 上的 OAuth 流程。当您单击添加 Consumer 时
-
将 重定向 URI 的值粘贴到 回调 URL 字段中。
-
确保您在 账户 部分中选择 Email 和 Read,以允许您的应用程序读取电子邮件。
-
-
记下 Bitbucket 在您创建 consumer 时显示的 Key 和 Secret 值。
-
在 Keycloak 中,将
Key
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Secret
的值粘贴到 客户端密钥 字段中。 -
点击 添加。
-
单击菜单中的 身份提供商。
-
从添加提供商列表中,选择 Facebook。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器选项卡中,打开 Meta for Developers。
-
单击我的应用。
-
选择创建应用。
添加用例 -
选择其他。
选择应用类型 -
选择 Consumer。
创建应用 -
填写所有必填字段。
-
单击创建应用。Meta 然后会将您带到仪表板。
添加产品 -
在 Facebook 登录框中单击 设置。
-
选择 Web。
-
将 重定向 URI 的值输入到 网站 URL 字段中,然后单击 保存。
-
在导航面板中,选择 应用设置 - 基本。
-
在 应用密钥 字段中单击 显示。
-
记下 应用 ID 和 应用密钥。
-
-
将
App ID
和App Secret
值从您的 Facebook 应用输入到 Keycloak 中的 客户端 ID 和 客户端密钥 字段中。 -
单击添加
-
在 默认 Scope 字段中输入所需的 scope。默认情况下,Keycloak 使用 email scope。有关 Facebook scope 的更多信息,请参阅 Graph API。
默认情况下,Keycloak 将配置文件请求发送到 graph.facebook.com/me?fields=id,name,email,first_name,last_name
。响应仅包含 id、name、email、first_name 和 last_name 字段。要从 Facebook 配置文件中获取其他字段,请添加相应的 scope 并在 其他用户配置文件字段
配置选项字段中添加字段名称。
GitHub
要使用 GitHub 登录,请执行以下步骤。
-
单击菜单中的 身份提供商。
-
从添加提供商列表中,选择 Github。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器选项卡中,创建一个 OAUTH 应用。
-
在创建应用时,将 重定向 URI 的值输入到 授权回调 URL 字段中。
-
记下您的 OAUTH 应用管理页面上的 Client ID 和 Client secret。
-
-
在 Keycloak 中,将
Client ID
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Client secret
的值粘贴到 客户端密钥 字段中。 -
点击 添加。
GitLab
-
单击菜单中的 身份提供商。
-
从添加提供商列表中,选择 GitLab。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器选项卡中,添加一个新的 GitLab 应用程序。
-
使用剪贴板中的 重定向 URI 作为 重定向 URI。
-
保存应用程序时,记下 应用程序 ID 和 密钥。
-
-
在 Keycloak 中,将
Application ID
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Secret
的值粘贴到 客户端密钥 字段中。 -
点击 添加。
-
单击菜单中的 身份提供商。
-
从添加提供商列表中,选择 Google。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器选项卡中,打开 Google Cloud Platform 控制台。
-
在您的 Google 应用的 Google 仪表板中,在左侧的导航菜单中,将鼠标悬停在 API 和服务 上,然后单击 OAuth 同意屏幕 选项。创建一个同意屏幕,确保同意屏幕的用户类型为 外部。
-
在 Google 仪表板中
-
单击 凭据 菜单。
-
单击 创建凭据 - OAuth 客户端 ID。
-
从 应用程序类型 列表中,选择 Web 应用程序。
-
使用剪贴板中的 重定向 URI 作为 已授权的重定向 URI
-
单击“创建”。
-
记下 您的客户端 ID 和 您的客户端密钥。
-
-
在 Keycloak 中,将
Your Client ID
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Your Client secret
的值粘贴到 客户端密钥 字段中。 -
单击添加
-
在 默认 Scope 字段中输入所需的 scope。默认情况下,Keycloak 使用以下 scope:openid profile email。有关 Google scope 的列表,请参阅 OAuth Playground。
-
要仅限制对您的 GSuite 组织成员的访问,请在 托管域 字段中输入 G Suite 域名。
-
点击 保存。
-
单击菜单中的 身份提供商。
-
从添加提供商列表中,选择 Instagram。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器选项卡中,打开 Meta for Developers。
-
单击我的应用。
-
选择创建应用。
添加用例 -
选择其他。
选择应用类型 -
选择 Consumer。
创建应用 -
填写所有必填字段。
-
单击创建应用。Meta 然后会将您带到仪表板。
-
在导航面板中,选择 应用设置 - 基本。
-
在页面底部选择 + 添加平台。
-
单击 [网站]。
-
输入您网站的 URL。
添加产品 -
从菜单中选择 仪表板。
-
在 Instagram Basic Display 框中单击 设置。
-
单击 创建新应用。
创建一个新的 Instagram 应用 ID -
在 显示名称 字段中输入一个值。
设置应用 -
将来自 Keycloak 的 重定向 URL 粘贴到 有效的 OAuth 重定向 URI 字段中。
-
将来自 Keycloak 的 重定向 URL 粘贴到 取消授权回调 URL 字段中。
-
将来自 Keycloak 的 重定向 URL 粘贴到 数据删除请求 URL 字段中。
-
在 Instagram 应用密钥 字段中单击 显示。
-
记下 Instagram 应用 ID 和 Instagram 应用密钥。
-
单击 应用审核 - 请求。
-
按照屏幕上的说明进行操作。
-
-
在 Keycloak 中,将
Instagram App ID
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Instagram App Secret
的值粘贴到 客户端密钥 字段中。 -
点击 添加。
-
单击菜单中的 身份提供商。
-
从添加提供程序列表中,选择 LinkedIn。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器标签页中,在 LinkedIn 开发者门户中创建应用。
-
创建应用后,点击 Auth 标签页。
-
将 Redirect URI 的值输入到 Authorized redirect URLs for your app 字段中。
-
记下 Your Client ID 和 Your Client Secret。
-
点击 Products 标签页,并为 Sign In with LinkedIn using OpenID Connect 产品请求访问权限。
-
-
在 Keycloak 中,将
Client ID
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Client Secret
的值粘贴到 Client Secret 字段中。 -
点击 添加。
Microsoft
-
单击菜单中的 身份提供商。
-
从添加提供程序列表中,选择 Microsoft。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器标签页中,在 Microsoft Azure 的 App registrations 下注册一个应用。
-
在 Redirect URI 部分,选择 Web 作为平台,并将 Redirect URI 的值粘贴到该字段中。
-
在 App registrations 下找到您的应用,并在 Certificates & secrets 部分添加一个新的客户端密钥。
-
记下已创建密钥的 Value。
-
在 Overview 部分记下 Application (client) ID。
-
-
在 Keycloak 中,将
Application (client) ID
的值粘贴到 Client ID 字段中。 -
在 Keycloak 中,将密钥的
Value
粘贴到 Client Secret 字段中。 -
点击 添加。
OpenShift 4
-
OpenShift 4 实例的证书存储在 Keycloak Truststore 中。
-
配置为使用 truststore 的 Keycloak 服务器。有关更多信息,请参阅配置 Truststore 指南。
-
单击菜单中的 身份提供商。
-
从添加提供程序列表中,选择 Openshift v4。
-
输入 Client ID 和 Client Secret,并在 Base URL 字段中,输入您的 OpenShift 4 实例的 API URL。此外,您可以将 Redirect URI 复制到剪贴板。
添加身份提供商 -
通过 OpenShift 4 控制台(Home → API Explorer → OAuth Client → Instances)或使用
oc
命令行工具注册您的客户端。$ oc create -f <(echo ' kind: OAuthClient apiVersion: oauth.openshift.io/v1 metadata: name: kc-client (1) secret: "..." (2) redirectURIs: - "<here you can paste the Redirect URI that you copied in the previous step>" (3) grantMethod: prompt (4) ')
1 | 您的 OAuth 客户端的 name 。在向 <openshift_master>/oauth/authorize 和 <openshift_master>/oauth/token 发出请求时,作为 client_id 请求参数传递。name 参数在 OAuthClient 对象和 Keycloak 配置中必须相同。 |
2 | Keycloak 用作 client_secret 请求参数的 secret 。 |
3 | 在向 <openshift_master>/oauth/authorize 和 <openshift_master>/oauth/token 发出的请求中指定的 redirect_uri 参数必须等于(或以...为前缀)redirectURIs 中的 URI 之一。正确配置它的最简单方法是从 Keycloak OpenShift 4 身份提供程序配置页面(Redirect URI 字段)复制粘贴它。 |
4 | grantMethod Keycloak 用于确定当此客户端请求令牌但尚未获得用户授权时要执行的操作。 |
最后,您应该在 Keycloak 实例的登录页面上看到 OpenShift 4 身份提供程序。点击它后,您应该被重定向到 OpenShift 4 登录页面。
有关更多信息,请参阅官方 OpenShift 文档。
PayPal
-
单击菜单中的 身份提供商。
-
从添加提供程序列表中,选择 PayPal。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器标签页中,打开 PayPal 开发者应用程序区域。
-
点击 Create App 以创建一个 PayPal 应用。
-
记下 Client ID 和 Client Secret。点击 Show 链接以查看密钥。
-
确保选中 Log in with PayPal。
-
在 Log in with PayPal 下,点击 Advanced Settings。
-
将 Return URL 字段的值设置为 Keycloak 中的 Redirect URI 值。请注意,URL 不能包含
localhost
。如果您想在本地使用 Keycloak,请将 Return URL 中的localhost
替换为127.0.0.1
,然后使用浏览器中的127.0.0.1
而不是localhost
访问 Keycloak。 -
确保选中 Full Name 和 Email 字段。
-
点击 Save,然后点击 Save Changes。
-
-
在 Keycloak 中,将
Client ID
的值粘贴到 客户端 ID 字段中。 -
在 Keycloak 中,将
Secret key 1
的值粘贴到 Client Secret 字段中。 -
点击 添加。
Stack Overflow
-
单击菜单中的 身份提供商。
-
从添加提供程序列表中,选择 Stack Overflow。
添加身份提供商 -
在单独的浏览器标签页中,登录 Stack Apps 上注册您的应用程序。
注册应用程序-
在 Application Name 字段中输入您的应用程序名称。
-
在 OAuth Domain 字段中输入 OAuth 域。
-
点击 Register Your Application。
设置
-
-
记下 Client Id、Client Secret 和 Key。
-
在 Keycloak 中,将
Client Id
的值粘贴到 Client ID 字段中。 -
在 Keycloak 中,将
Client Secret
的值粘贴到 Client Secret 字段中。 -
在 Keycloak 中,将
Key
的值粘贴到 Key 字段中。 -
点击 添加。
-
一个 Twitter 开发者帐户。
-
单击菜单中的 身份提供商。
-
从添加提供程序列表中,选择 Twitter。
添加身份提供商 -
将 重定向 URI 的值复制到剪贴板。
-
在单独的浏览器标签页中,在 Twitter 应用程序管理中创建一个应用。
-
输入应用名称,然后点击 Next。
-
记下 API Key 和 API Key Secret 的值,然后点击 App settings。
-
在 User authentication settings 部分,点击 Set up 按钮。
-
选择 Web App 作为 Type of App。
-
将 Redirect URL 的值粘贴到 Callback URI / Redirect URL 字段中。
-
Website URL 的值可以是除
localhost
之外的任何有效 URL。 -
点击 Save,然后点击 Done。
-
-
在 Keycloak 中,将
API Key
的值粘贴到 Client ID 字段中。 -
在 Keycloak 中,将
API Key Secret
的值粘贴到 Client Secret 字段中。 -
点击 添加。
OpenID Connect v1.0 身份提供程序
Keycloak 基于 OpenID Connect 协议代理身份提供程序。这些身份提供程序 (IDP) 必须支持规范中定义的授权码流程,以验证用户身份并授权访问。
-
单击菜单中的 身份提供商。
-
从
Add provider
列表中,选择OpenID Connect v1.0
。添加身份提供商 -
输入您的初始配置选项。有关配置选项的更多信息,请参阅通用 IDP 配置。
表 2. OpenID Connect 配置 配置 描述 授权 URL
OIDC 协议要求的授权 URL 端点。
令牌 URL
OIDC 协议要求的令牌 URL 端点。
注销 URL
OIDC 协议中的注销 URL 端点。此值为可选。
后端注销
发送到 IDP 的后台、带外 REST 请求,用于注销用户。某些 IDP 仅通过浏览器重定向执行注销,因为它们可能使用浏览器 Cookie 识别会话。
用户信息 URL
OIDC 协议定义的端点。此端点指向用户个人资料信息。
客户端身份验证
定义 Keycloak 与授权码流程一起使用的客户端身份验证方法。对于使用私钥签名的 JWT,Keycloak 使用 realm 私钥。在其他情况下,定义客户端密钥。有关更多信息,请参阅客户端身份验证规范。
客户端 ID
充当外部 IDP 的 OIDC 客户端的 realm。如果您使用授权码流程与外部 IDP 交互,则 realm 必须具有 OIDC 客户端 ID。
客户端密钥
来自外部vault的客户端密钥。如果您使用授权码流程,则此密钥是必需的。
客户端断言签名算法
用于创建 JWT 断言作为客户端身份验证的签名算法。对于使用私钥签名的 JWT 或作为 jwt 的客户端密钥,这是必需的。如果未指定算法,则会采用以下算法。在使用私钥签名的 JWT 的情况下,采用
RS256
。在作为 jwt 的客户端密钥的情况下,采用HS256
。客户端断言受众
用于客户端断言的受众。默认值为 IDP 的令牌端点 URL。
颁发者
Keycloak 针对此值验证来自 IDP 的响应中的颁发者声明。
默认范围
Keycloak 随身份验证请求发送的 OIDC 范围列表。默认值为
openid
。每个范围用空格分隔。提示
OIDC 规范中的提示参数。通过此参数,您可以强制重新身份验证和其他选项。有关更多详细信息,请参阅规范。
接受来自客户端的 prompt=none 转发
指定 IDP 是否接受包含
prompt=none
查询参数的转发身份验证请求。如果 realm 收到带有prompt=none
的身份验证请求,则 realm 会检查用户当前是否已通过身份验证,如果用户尚未登录,则返回login_required
错误。当 Keycloak 确定身份验证请求的默认 IDP 时(使用kc_idp_hint
查询参数或 realm 具有默认 IDP),您可以将带有prompt=none
的身份验证请求转发到默认 IDP。默认 IDP 在此处检查用户的身份验证。由于并非所有 IDP 都支持带有prompt=none
的请求,因此 Keycloak 使用此开关来指示默认 IDP 在重定向身份验证请求之前支持该参数。如果用户在 IDP 中未通过身份验证,则客户端仍然会收到
login_required
错误。如果用户在 IDP 中已通过身份验证,则如果 Keycloak 必须显示需要用户交互的身份验证页面,则客户端仍然可能收到interaction_required
错误。此身份验证包括必需的操作(例如,密码更改)、同意屏幕以及设置为通过first broker login
流程或post broker login
流程显示的屏幕。验证签名
指定 Keycloak 是否验证此 IDP 签名的外部 ID 令牌上的签名。如果为开启,则 Keycloak 必须知道外部 OIDC IDP 的公钥。出于性能目的,Keycloak 缓存外部 OIDC 身份提供程序的公钥。
使用 JWKS URL
如果
Validate Signatures
为开启,则此开关适用。如果 Use JWKS URL 为开启,则 Keycloak 从 JWKS URL 下载 IDP 的公钥。当身份提供程序生成新的密钥对时,会下载新密钥。如果为关闭,则 Keycloak 使用其数据库中的公钥(或证书),因此当 IDP 密钥对更改时,也将新密钥导入到 Keycloak 数据库。JWKS URL
指向 IDP JWK 密钥位置的 URL。有关更多信息,请参阅 JWK 规范。如果您使用外部 Keycloak 作为 IDP,则可以使用类似 http://broker-keycloak:8180/realms/test/protocol/openid-connect/certs 的 URL,如果您的代理 Keycloak 运行在 http://broker-keycloak:8180 上,并且其 realm 为
test
。验证公钥
PEM 格式的公钥,Keycloak 使用此公钥来验证外部 IDP 签名。如果
使用 JWKS URL
为关闭,则应用此密钥。验证公钥 ID
如果使用 JWKS URL 为关闭,则应用此设置。此设置指定 PEM 格式公钥的 ID。由于没有从密钥计算密钥 ID 的标准方法,因此外部身份提供商可以使用与 Keycloak 不同的算法。如果未指定此字段的值,则 Keycloak 将对所有请求使用验证公钥,而不管外部 IDP 发送的密钥 ID 如何。当开启时,此字段的值是 Keycloak 用于验证来自提供商的签名的密钥 ID,并且必须与 IDP 指定的密钥 ID 匹配。
您可以通过提供指向 OpenID 提供商元数据的 URL 或文件来导入所有此配置数据。如果您连接到 Keycloak 外部 IDP,则可以从 <root>/realms/{realm-name}/.well-known/openid-configuration
导入 IDP 设置。此链接是一个 JSON 文档,描述了有关 IDP 的元数据。
如果您想在提供商中使用 Json Web Encryption (JWE) ID 令牌或 UserInfo 响应,则 IDP 需要知道与 Keycloak 一起使用的公钥。提供商使用为不同加密算法定义的 realm 密钥 来解密令牌。Keycloak 提供了一个标准的 JWKS 端点,IDP 可以使用该端点自动下载密钥。
SAML v2.0 身份提供商
Keycloak 可以代理基于 SAML v2.0 协议的身份提供商。
-
单击菜单中的 身份提供商。
-
从
添加提供商
列表中,选择SAML v2.0
。添加身份提供商 -
输入您的初始配置选项。有关配置选项的更多信息,请参阅通用 IDP 配置。
配置 | 描述 |
---|---|
服务提供商实体 ID |
远程身份提供商用于标识来自此服务提供商的请求的 SAML 实体 ID。默认情况下,此设置设置为 realm 的基本 URL |
身份提供商实体 ID |
用于验证接收到的 SAML 断言的颁发者的实体 ID。如果为空,则不执行颁发者验证。 |
单点登录服务 URL |
启动身份验证过程的 SAML 端点。如果您的 SAML IDP 发布了 IDP 实体描述符,则此字段的值将在其中指定。 |
Artifact 服务 URL |
SAML Artifact 解析端点。如果您的 SAML IDP 发布了 IDP 实体描述符,则此字段的值将在其中指定。 |
单点注销服务 URL |
SAML 注销端点。如果您的 SAML IDP 发布了 IDP 实体描述符,则此字段的值将在其中指定。 |
后端注销 |
如果您的 SAML IDP 支持后通道注销,请将此开关切换为开启。 |
NameID 策略格式 |
与名称标识符格式对应的 URI 引用。默认情况下,Keycloak 将其设置为 |
主体类型 |
指定 SAML 断言的哪个部分将用于识别和跟踪外部用户身份。可以是主体 NameID 或 SAML 属性(按名称或友好名称)。主体 NameID 值不能与 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' NameID 策略格式值一起设置。 |
主体属性 |
如果主体类型为非空,则此字段指定标识属性的名称(“属性 [名称]”)或友好名称(“属性 [友好名称]”)。 |
允许创建 |
允许外部身份提供商创建新的标识符来表示主体。 |
HTTP-POST 绑定响应 |
控制响应外部 IDP 发送的任何 SAML 请求的 SAML 绑定。当关闭时,Keycloak 使用重定向绑定。 |
ARTIFACT 绑定响应 |
控制响应外部 IDP 发送的任何 SAML 请求的 SAML 绑定。当关闭时,Keycloak 评估 HTTP-POST 绑定响应配置。 |
HTTP-POST 绑定用于 AuthnRequest |
控制从外部 IDP 请求身份验证时的 SAML 绑定。当关闭时,Keycloak 使用重定向绑定。 |
需要签名 AuthnRequest |
当开启时,Keycloak 使用 realm 的密钥对对发送到外部 SAML IDP 的请求进行签名。 |
需要签名断言 |
指示此服务提供商是否期望签名的断言。 |
需要加密断言 |
指示此服务提供商是否期望加密的断言。 |
签名算法 |
如果需要签名 AuthnRequest 为开启,则要使用的签名算法。请注意,基于 |
加密算法 |
SAML IDP 用于加密 SAML 文档、断言或 ID 的加密算法。用于解密 SAML 文档部分的相应解密密钥将根据此配置的算法选择,并且应在 realm 密钥中可用,以用于加密 (ENC)。如果未配置算法,则允许任何支持的算法,并且将根据 SAML 文档本身中指定的算法选择解密密钥。 |
SAML 签名密钥名称 |
使用 POST 绑定发送的已签名 SAML 文档在 |
强制身份验证 |
即使在用户已经登录的情况下,用户也必须在外部 IDP 输入其凭据。 |
验证签名 |
当开启时,realm 期望来自外部 IDP 的 SAML 请求和响应是数字签名的。 |
元数据描述符 URL |
身份提供商发布 |
使用元数据描述符 URL |
当开启时,用于验证签名的证书会自动从 当选项为关闭时, |
验证 X509 证书 |
当 |
签署服务提供商元数据 |
当开启时,Keycloak 使用 realm 的密钥对对 SAML 服务提供商元数据描述符 进行签名。 |
传递主题 |
控制 Keycloak 是否将 |
属性消费服务索引 |
标识要向远程 IDP 请求的属性集。Keycloak 自动将身份提供商配置中映射的属性添加到自动生成的 SP 元数据文档。 |
属性消费服务名称 |
在自动生成的 SP 元数据文档中声明的属性集的描述性名称。 |
您可以通过提供指向外部 IDP 的 SAML IDP 实体描述符的 URL 或文件来导入所有配置数据。如果您连接到 Keycloak 外部 IDP,则可以从 URL <root>/realms/{realm-name}/protocol/saml/descriptor
导入 IDP 设置。此链接是一个 XML 文档,描述了有关 IDP 的元数据。您还可以通过提供指向外部 SAML IDP 的实体描述符的 URL 或 XML 文件来导入所有此配置数据以进行连接。
请求特定的 AuthnContext
身份提供商方便客户端指定验证用户身份的身份验证方法的约束。例如,请求 MFA、Kerberos 身份验证或安全要求。这些约束使用特定的 AuthnContext 标准。客户端可以请求一个或多个标准,并指定身份提供商必须如何匹配请求的 AuthnContext,完全匹配,或通过满足其他等效项来匹配。
您可以通过在“请求的 AuthnContext 约束”部分中添加 ClassRefs 或 DeclRefs 来列出您的服务提供商需要的标准。通常,您需要提供 ClassRefs 或 DeclRefs 中的一个,因此请查看您的身份提供商文档,了解支持哪些值。如果不存在 ClassRefs 或 DeclRefs,则身份提供商不会强制执行其他约束。
配置 | 描述 |
---|---|
比较 |
身份提供商用于评估上下文要求的方法。可用值为 |
AuthnContext ClassRefs |
描述所需标准的 AuthnContext ClassRefs。 |
AuthnContext DeclRefs |
描述所需标准的 AuthnContext DeclRefs。 |
客户端建议的身份提供商
OIDC 应用程序可以通过提示他们想要使用的身份提供商来绕过 Keycloak 登录页面。您可以通过在授权码流程授权端点中设置 kc_idp_hint
查询参数来启用此功能。
使用 Keycloak OIDC 客户端适配器,您可以在访问应用程序中的受保护资源时指定此查询参数。
例如
GET /myapplication.com?kc_idp_hint=facebook HTTP/1.1
Host: localhost:8080
在这种情况下,您的 realm 必须具有别名为 facebook
的身份提供商。如果此提供商不存在,则会显示登录表单。
如果您使用的是 JavaScript 适配器,您也可以通过以下方式实现相同的行为
const keycloak = new Keycloak({
url: "http://keycloak-server",
realm: "my-realm",
clientId: "my-app"
);
await keycloak.createLoginUrl({
idpHint: 'facebook'
});
使用 kc_idp_hint
查询参数,如果您为 身份提供商重定向器
身份验证器配置了一个默认身份提供商,则客户端可以覆盖该默认身份提供商。客户端可以通过将 kc_idp_hint
查询参数设置为空值来禁用自动重定向。
映射声明和断言
您可以将外部 IDP(您正在使用其进行身份验证)提供的 SAML 和 OpenID Connect 元数据导入到 realm 中。导入后,您可以提取用户配置文件元数据和其他信息,以便您可以将其提供给您的应用程序。
每个使用外部身份提供商登录到您的 realm 的用户在本地 Keycloak 数据库中都有一个条目,该条目基于来自 SAML 或 OIDC 断言和声明的元数据。
-
单击菜单中的 身份提供商。
-
在列表中选择一个身份提供商。
-
单击 映射器 选项卡。
身份提供商映射器 -
单击 添加映射器。
身份提供商映射器 -
为 同步模式覆盖 选择一个值。当用户根据此设置重复登录时,映射器会更新用户信息。
-
选择 legacy 以使用以前 Keycloak 版本的行为。
-
选择 import 以从用户首次通过特定身份提供商首次登录 Keycloak 期间在 Keycloak 中创建用户时导入数据。
-
选择 force 以在每次用户登录时更新用户数据。
-
选择 inherit 以使用在身份提供商中配置的同步模式。所有其他选项都将覆盖此同步模式。
-
-
从 映射器类型 列表中选择一个映射器。将鼠标悬停在 映射器类型 上以查看映射器的描述以及要为映射器输入的配置。
-
点击 保存。
对于基于 JSON 的声明,您可以使用点表示法进行嵌套,并使用方括号按索引访问数组字段。例如,contact.address[0].country
。
要调查社交提供商提供的用户配置文件 JSON 数据的结构,您可以在启动服务器时启用 DEBUG
级别日志记录器 org.keycloak.social.user_profile_dump
。
可用的用户会话数据
在用户通过外部 IDP 登录后,Keycloak 会存储用户会话 note 数据,您可以访问这些数据。此数据可以使用令牌或 SAML 断言传播到请求登录的客户端,并通过适当的客户端映射器传递回客户端。
- identity_provider
-
用于执行登录的代理的 IDP 别名。
- identity_provider_identity
-
当前已认证用户的 IDP 用户名。通常(但不总是)与 Keycloak 用户名相同。例如,Keycloak 可以将用户 `john` 链接到 Facebook 用户
john123@gmail.com
。在这种情况下,用户会话 note 的值是john123@gmail.com
。
您可以使用类型为 User Session Note
的 协议映射器 将此信息传播到您的客户端。
首次登录流程
当用户通过身份代理登录时,Keycloak 会导入用户的一些方面并将其链接到 realm 的本地数据库中。当 Keycloak 通过外部身份提供程序成功验证用户身份时,可能存在两种情况:
-
Keycloak 已经导入用户帐户并将其与已认证的身份提供程序帐户链接。在这种情况下,Keycloak 以现有用户身份进行身份验证,并重定向回应用程序。
-
Keycloak 中不存在此用户的帐户。通常,您会注册一个新帐户并将其导入到 Keycloak 数据库中,但也可能存在具有相同电子邮件地址的现有 Keycloak 帐户。自动将现有本地帐户链接到外部身份提供程序可能存在安全漏洞。您不能总是信任从外部身份提供程序获取的信息。
不同的组织在处理某些情况时有不同的要求。使用 Keycloak,您可以使用 IDP 设置中的 First Login Flow
选项,为首次从外部 IDP 登录的用户选择一个工作流。默认情况下,First Login Flow
选项指向 first broker login
流,但您可以为不同的身份提供程序使用您自己的流或不同的流。
该流位于管理控制台的身份验证选项卡下。当您选择 First Broker Login
流时,您会看到默认使用的身份验证器。您可以重新配置现有流。例如,您可以禁用某些身份验证器,将其中一些标记为 required
,或配置某些身份验证器。
您还可以创建新的身份验证流,编写您自己的 Authenticator 实现,并在您的流中使用它。有关更多信息,请参阅服务器开发人员指南。
默认首次登录流程身份验证器
- 审查个人资料
-
-
此身份验证器显示个人资料信息页面,以便用户可以审查 Keycloak 从身份提供程序检索到的个人资料。
-
您可以在操作菜单中设置
Update Profile On First Login
选项。 -
当设置为 ON 时,用户将看到个人资料页面,请求提供更多信息以联合用户的身份。
-
当设置为 missing 时,如果身份提供程序未提供强制性信息(例如电子邮件、名字或姓氏),则用户将看到个人资料页面。
-
当设置为 OFF 时,除非用户在
Confirm Link Existing Account
身份验证器显示的页面中单击稍后阶段的Review profile info
链接,否则不会显示个人资料页面。
-
- 如果唯一则创建用户
-
此身份验证器检查是否已存在与身份提供程序帐户具有相同电子邮件或用户名的 Keycloak 帐户。如果不存在,则身份验证器将创建一个新的本地 Keycloak 帐户,并将其与身份提供程序链接,整个流程完成。否则,它将转到下一个
Handle Existing Account
子流。如果您始终希望确保没有重复帐户,则可以将此身份验证器标记为REQUIRED
。在这种情况下,如果存在现有 Keycloak 帐户,用户将看到错误页面,并且用户需要通过帐户管理链接身份提供程序帐户。-
此身份验证器验证是否已存在与身份提供程序的帐户具有相同电子邮件或用户名的 Keycloak 帐户。
-
如果帐户不存在,则身份验证器创建一个本地 Keycloak 帐户,将此帐户与身份提供程序链接,并终止流程。
-
如果帐户存在,则身份验证器实现下一个
Handle Existing Account
子流。 -
要确保没有重复帐户,您可以将此身份验证器标记为
REQUIRED
。如果 Keycloak 帐户存在,用户将看到错误页面,并且用户必须通过帐户管理链接其身份提供程序帐户。
-
- 确认链接现有帐户
-
-
在信息页面上,用户将看到一个具有相同电子邮件的 Keycloak 帐户。用户可以再次审查他们的个人资料,并使用不同的电子邮件或用户名。流程重新开始,并返回到
Review Profile
身份验证器。 -
或者,用户可以确认他们想要将其身份提供程序帐户与其现有 Keycloak 帐户链接。
-
如果您不希望用户看到此确认页面,并直接通过电子邮件验证或重新身份验证链接身份提供程序帐户,请禁用此身份验证器。
-
- 通过电子邮件验证现有帐户
-
-
默认情况下,此身份验证器为
ALTERNATIVE
。如果 realm 配置了 SMTP 设置,Keycloak 将使用此身份验证器。 -
身份验证器会向用户发送电子邮件,以确认他们想要将身份提供程序与其 Keycloak 帐户链接。
-
如果您不想通过电子邮件确认链接,而是希望用户使用密码重新身份验证,请禁用此身份验证器。
-
- 通过重新身份验证验证现有帐户
-
-
如果电子邮件身份验证器不可用,请使用此身份验证器。例如,您尚未为您的 realm 配置 SMTP。此身份验证器会显示一个登录屏幕,供用户进行身份验证,以便将其 Keycloak 帐户与身份提供程序链接。
-
用户还可以使用已链接到其 Keycloak 帐户的另一个身份提供程序重新进行身份验证。
-
您可以强制用户使用 OTP。否则,它是可选的,并且在您为用户帐户设置了 OTP 时使用。
-
自动链接现有首次登录流程
在用户可以使用任意用户名或电子邮件地址自行注册的通用环境中,AutoLink 身份验证器是危险的。除非您仔细管理用户注册并分配用户名和电子邮件地址,否则请勿使用此身份验证器。 |
要配置一个自动链接用户而无需提示的首次登录流程,请创建一个包含以下两个身份验证器的新流程:
- 如果唯一则创建用户
-
此身份验证器确保 Keycloak 处理唯一用户。将身份验证器要求设置为 Alternative。
- 自动设置现有用户
-
此身份验证器在没有验证的情况下将现有用户设置为身份验证上下文。将身份验证器要求设置为“Alternative”。
此设置是可用的最简单设置,但可以使用其他身份验证器。例如:
|
禁用自动用户创建
默认的首次登录流程会查找与外部身份匹配的 Keycloak 帐户,并提供链接它们的选项。如果不存在匹配的 Keycloak 帐户,则流程会自动创建一个。
对于某些设置,此默认行为可能不合适。一个示例是当您使用只读 LDAP 用户存储时,其中所有用户都是预先创建的。在这种情况下,您必须关闭自动用户创建。
要禁用用户创建:
-
点击菜单中的 身份验证。
-
从列表中选择 First Broker Login。
-
将 Create User If Unique 设置为 DISABLED。
-
将 Confirm Link Existing Account 设置为 DISABLED。
此配置还意味着 Keycloak 本身将无法确定哪个内部帐户对应于外部身份。因此,Verify Existing Account By Re-authentication
身份验证器将要求用户提供用户名和密码。
启用或禁用身份提供程序的用户创建完全独立于 realm 的 用户注册开关。您可以启用身份提供程序的用户创建,同时禁用 realm 登录设置中的用户自助注册,反之亦然。 |
检测现有用户首次登录流程
为了配置一个首次登录流程,其中:
-
只有已在此 realm 中注册的用户才能登录,
-
用户会被自动链接,而无需提示,
创建一个包含以下两个身份验证器的新流程:
- 检测现有代理用户
-
此身份验证器确保处理唯一用户。将身份验证器要求设置为
REQUIRED
。 - 自动设置现有用户
-
自动将现有用户设置为身份验证上下文,无需任何验证。将身份验证器要求设置为
REQUIRED
。
您必须将身份提供程序配置的 First Login Flow
设置为该流程。如果您想使用身份提供程序属性更新用户个人资料(姓氏、名字…),您也可以将 Sync Mode
设置为 force
。
如果您想将身份委托给其他身份提供程序(例如 GitHub、Facebook …),但又想管理哪些用户可以登录,则可以使用此流程。 |
使用此配置,Keycloak 无法确定哪个内部帐户对应于外部身份。Verify Existing Account By Re-authentication 身份验证器会要求提供程序提供用户名和密码。
覆盖现有代理链接
当需要将另一个帐户链接到同一身份提供程序内的同一 Keycloak 帐户时,您可以配置以下身份验证器。
- 确认覆盖现有链接
-
此身份验证器将检测用户的现有代理链接,并显示一个确认页面以确认覆盖现有代理链接。将身份验证器要求设置为 REQUIRED。
此身份验证器的典型用途是以下场景:
-
例如,考虑一个 Keycloak 用户
john
,其电子邮件为john@gmail.com
。该用户链接到身份提供程序google
,其google
用户名为john@gmail.com
。 -
然后,例如 Keycloak 用户
john
创建了一个新的 Google 帐户,电子邮件为john-new@gmail.com
。 -
然后在登录 Keycloak 期间,用户使用新的用户名(例如
john-new@gmail.com
)向身份提供程序google
进行了身份验证,该用户名尚未链接到任何 Keycloak 帐户(因为 Keycloak 帐户john
仍然链接到google
用户john@gmail.com
),因此触发了 first-broker-login 流程。 -
在 first-broker-login 期间,Keycloak 用户
john
以某种方式通过身份验证(默认的 first-broker-login 重新身份验证,或者例如通过Detect existing broker user
等身份验证器)。 -
现在,通过身份验证流程中的此身份验证器,可以在用户
john
确认后,将 Keycloak 用户john
的google
身份提供程序链接覆盖为新的google
用户john-new@gmail.com
链接。
在创建包含此身份验证器的身份验证流程时,请确保在其他身份验证器已通过其他方式(通过重新身份验证或在上述 Detect existing broker user
之后)建立 Keycloak 用户之后添加此身份验证器。
登录后流程
当您希望在每次使用特定身份提供程序登录后触发一些额外的身份验证操作时,登录后流程非常有用。例如,您可能希望在每次 Keycloak 登录到 Facebook
后触发双因素身份验证,因为 Facebook
在其登录期间不提供双因素身份验证。
一旦您使用所需的步骤设置了身份验证流程,请在配置身份提供程序时将其设置为 Post login flow
。
登录后流程示例
在身份提供程序登录后请求双因素身份验证
最简单的方法是强制使用一种特定的双因素方法进行身份验证。例如,当请求 OTP 时,流程可以如下所示,仅配置一个身份验证器。当用户帐户上未设置 OTP 时,此类型的流程要求用户在首次使用身份提供程序登录期间配置 OTP。
更复杂的设置可以包括配置为 ALTERNATIVE
的多种双因素身份验证方法。在这种情况下,请确保如果用户尚未在其帐户上配置任何双因素身份验证,则会要求用户设置其中一种方法。这可以按如下方式完成:
-
确保其中一种双因素方法在首次登录流程中配置为
REQUIRED
。如果您期望所有用户都通过身份提供程序登录注册,则此方法可以工作。 -
将双因素方法作为
ALTERNATIVE
包装到条件子流中,例如一个名为2FA
的子流,并创建另一个条件子流,例如一个名为OTP if no 2FA
的子流,该子流仅在前一个子流未执行时触发,并将要求用户添加一种双因素方法(例如,OTP)。类似的流程配置示例在身份验证流程章节的条件部分中提供。
为专用客户端请求额外的身份验证步骤
在某些情况下,客户端或客户端组可能需要在身份提供程序登录后执行一些额外的步骤。以下是一个流程示例,该流程规定,当请求客户端 scope foo
时,要求用户在身份提供程序登录后使用 OTP 进行身份验证。
这是配置 Condition - client scope
以请求指定客户端范围的示例。
请求的客户端需要在其上设置此客户端范围,可以设置为默认或可选。在后一种情况下,仅当客户端请求客户端范围时才执行流程(例如,在 OIDC/OAuth2 客户端登录的情况下,通过 scope
参数)。
检索外部 IDP 令牌
使用 Keycloak,您可以使用 IDP 设置页面上的 Store Token
配置选项来存储来自外部 IDP 身份验证过程的令牌和响应。
应用程序代码可以检索这些令牌和响应,以导入额外的用户信息或安全地请求外部 IDP。例如,应用程序可以使用 Google 令牌来使用其他 Google 服务和 REST API。要检索特定身份提供程序的令牌,请按如下方式发送请求
GET /realms/{realm-name}/broker/{provider_alias}/token HTTP/1.1
Host: localhost:8080
Authorization: Bearer <KEYCLOAK ACCESS TOKEN>
应用程序必须使用 Keycloak 进行身份验证并接收访问令牌。此访问令牌必须设置 broker
客户端级角色 read-token
,因此用户必须具有此角色的角色映射,并且客户端应用程序必须在其范围内具有该角色。在这种情况下,由于您正在访问 Keycloak 中的受保护服务,请发送用户身份验证期间由 Keycloak 颁发的访问令牌。您可以通过将存储令牌可读开关设置为开启,在代理配置页面中将此角色分配给新导入的用户。
这些外部令牌可以通过再次通过提供程序登录或使用客户端发起的帐户链接 API 重新建立。
SSO 协议
本节讨论身份验证协议、Keycloak 身份验证服务器以及由 Keycloak 身份验证服务器保护的应用程序如何与这些协议交互。
OpenID Connect
OpenID Connect (OIDC) 是一种身份验证协议,它是 OAuth 2.0 的扩展。
OAuth 2.0 是一个用于构建授权协议的框架,并且是不完整的。然而,OIDC 是一种完整的身份验证和授权协议,它使用 Json Web Token (JWT) 标准。 JWT 标准定义了身份令牌 JSON 格式以及以紧凑且 Web 友好的方式对数据进行数字签名和加密的方法。
一般来说,OIDC 实现了两种用例。第一种情况是应用程序请求 Keycloak 服务器验证用户身份。成功登录后,应用程序会收到一个身份令牌和一个访问令牌。身份令牌包含用户信息,包括用户名、电子邮件和个人资料信息。领域对访问令牌进行数字签名,其中包含访问信息(例如用户角色映射),应用程序使用这些信息来确定用户可以访问应用程序中的哪些资源。
第二种用例是客户端访问远程服务。
-
客户端从 Keycloak 请求访问令牌,以代表用户调用远程服务。
-
Keycloak 验证用户身份,并征求用户同意授予对请求客户端的访问权限。
-
客户端收到由领域数字签名的访问令牌。
-
客户端使用访问令牌对远程服务发出 REST 请求。
-
远程 REST 服务提取访问令牌。
-
远程 REST 服务验证令牌签名。
-
远程 REST 服务根据令牌内的访问信息,决定处理还是拒绝请求。
OIDC 身份验证流程
OIDC 有几种方法或流程,客户端或应用程序可以使用这些方法或流程来验证用户身份并接收身份和访问令牌。该方法取决于请求访问的应用程序或客户端的类型。
授权码流程
授权码流程是一种基于浏览器的协议,适用于验证和授权基于浏览器的应用程序。它使用浏览器重定向来获取身份和访问令牌。
-
用户使用浏览器连接到应用程序。应用程序检测到用户未登录到应用程序。
-
应用程序将浏览器重定向到 Keycloak 进行身份验证。
-
应用程序在浏览器重定向中传递回调 URL 作为查询参数。Keycloak 在成功身份验证后使用该参数。
-
Keycloak 验证用户身份并创建一个一次性的、短期的临时代码。
-
Keycloak 使用回调 URL 重定向到应用程序,并在回调 URL 中添加临时代码作为查询参数。
-
应用程序提取临时代码,并对 Keycloak 进行后台 REST 调用,以交换代码以获取身份和访问以及刷新令牌。为了防止重放攻击,临时代码不能使用多次。
系统在令牌的生命周期内容易受到令牌被盗的攻击。出于安全和可扩展性原因,访问令牌通常设置为快速过期,以便后续令牌请求失败。如果令牌过期,应用程序可以使用登录协议发送的额外刷新令牌来获取新的访问令牌。 |
机密客户端在交换临时代码以获取令牌时提供客户端密钥。公共客户端不需要提供客户端密钥。当严格执行 HTTPS 并且为客户端注册的重定向 URI 受到严格控制时,公共客户端是安全的。 HTML5/JavaScript 客户端必须是公共客户端,因为没有办法安全地将客户端密钥传输到 HTML5/JavaScript 客户端。有关更多详细信息,请参阅 管理客户端 章节。
Keycloak 还支持 Proof Key for Code Exchange 规范。
隐式流程
隐式流程是一种基于浏览器的协议。它类似于授权码流程,但请求较少且没有刷新令牌。
当令牌通过重定向 URI 传输时,存在访问令牌在浏览器历史记录中泄漏的可能性(见下文)。 此外,此流程不为客户端提供刷新令牌。因此,访问令牌必须是长期有效的,或者用户必须在令牌过期时重新进行身份验证。 我们不建议使用此流程。支持此流程是因为它在 OIDC 和 OAuth 2.0 规范中。 |
该协议的工作方式如下
-
用户使用浏览器连接到应用程序。应用程序检测到用户未登录到应用程序。
-
应用程序将浏览器重定向到 Keycloak 进行身份验证。
-
应用程序在浏览器重定向中传递回调 URL 作为查询参数。Keycloak 在成功身份验证后使用该查询参数。
-
Keycloak 验证用户身份并创建身份和访问令牌。Keycloak 使用回调 URL 重定向到应用程序,并在回调 URL 中额外添加身份和访问令牌作为查询参数。
-
应用程序从回调 URL 中提取身份和访问令牌。
资源所有者密码凭据授权(直接访问授权)
直接访问授权供 REST 客户端使用,以代表用户获取令牌。它是一个包含以下内容的 HTTP POST 请求
-
用户的凭据。凭据在表单参数中发送。
-
客户端的 ID。
-
客户端密钥(如果是机密客户端)。
HTTP 响应包含身份、访问和刷新令牌。
刷新令牌授权
默认情况下,Keycloak 在大多数流程的令牌响应中返回刷新令牌。一些例外情况是上面描述的隐式流程或客户端凭据授权。
刷新令牌与 SSO 浏览器会话的用户会话相关联,并且在用户会话的生命周期内有效。但是,客户端应至少每隔指定的时间间隔发送一次刷新令牌请求。否则,会话可能被视为“空闲”并可能过期。有关更多信息,请参阅 超时部分。
Keycloak 支持 离线令牌,即使相应的浏览器 SSO 会话已过期,通常在客户端需要使用刷新令牌时也可以使用离线令牌。
刷新令牌轮换
可以指定刷新令牌一旦使用即被视为无效。这意味着客户端必须始终保存来自上次刷新响应的刷新令牌,因为 Keycloak 不再认为已使用的较旧的刷新令牌有效。这可以通过使用 超时部分中指定的撤销刷新令牌选项来设置。
设备授权授权
这由在输入功能有限或缺少合适浏览器的联网设备上运行的客户端使用。以下是该协议的简要概述
-
应用程序向 Keycloak 请求设备代码和用户代码。Keycloak 创建设备代码和用户代码。Keycloak 返回包含设备代码和用户代码的响应给应用程序。
-
应用程序向用户提供用户代码和验证 URI。用户访问验证 URI 以使用另一个浏览器进行身份验证。您可以定义一个简短的 verification_uri,它将被重定向到 Keycloak 验证 URI (/realms/realm_name/device) 在 Keycloak 外部 - 例如在代理中。
-
应用程序重复轮询 Keycloak,以查找用户是否完成用户授权。如果用户身份验证完成,应用程序将设备代码交换为身份、访问和刷新令牌。
客户端发起的后台通道身份验证授权
此功能供希望直接与 OpenID Provider 通信以启动身份验证流程的客户端使用,而无需像 OAuth 2.0 的授权码许可那样通过用户浏览器重定向。以下是该协议的简要概述
-
客户端向 Keycloak 请求一个 auth_req_id,用于标识客户端发出的身份验证请求。Keycloak 创建 auth_req_id。
-
收到此 auth_req_id 后,客户端需要重复轮询 Keycloak,以获取来自 Keycloak 的访问令牌、刷新令牌和 ID 令牌,以换取 auth_req_id,直到用户通过身份验证。
管理员可以将客户端发起的后台通道身份验证 (CIBA) 相关操作配置为每个 realm 的CIBA 策略
。
另请参阅 Keycloak 文档的其他位置,例如后台通道身份验证端点和客户端发起的后台通道身份验证许可,位于安全应用部分。
CIBA 策略
管理员在 Admin Console
上执行以下操作
-
打开
Authentication → CIBA Policy
选项卡。 -
配置项目并单击
Save
。
可配置的项目及其描述如下。
配置 | 描述 |
---|---|
后台通道令牌传递模式 |
指定 CD(消费设备)如何获取身份验证结果和相关令牌。有三种模式:“poll”、“ping”和“push”。Keycloak 仅支持“poll”。默认设置为“poll”。此配置是必需的。有关更多详细信息,请参阅 CIBA 规范。 |
过期时间 |
“auth_req_id”的过期时间,单位为秒,自收到身份验证请求起算。默认设置为 120 秒。此配置是必需的。有关更多详细信息,请参阅 CIBA 规范。 |
间隔 |
CD(消费设备)在轮询令牌端点请求之间需要等待的间隔,单位为秒。默认设置为 5 秒。此配置是可选的。有关更多详细信息,请参阅 CIBA 规范。 |
请求身份验证的用户提示 |
识别正在请求身份验证的终端用户的方式。默认设置为“login_hint”。有三种模式:“login_hint”、“login_hint_token”和“id_token_hint”。Keycloak 仅支持“login_hint”。此配置是必需的。有关更多详细信息,请参阅 CIBA 规范。 |
提供程序设置
CIBA 许可使用以下两个提供程序。
-
身份验证通道提供程序:提供 Keycloak 与实际通过 AD(身份验证设备)验证用户的实体之间的通信。
-
用户解析器提供程序:从客户端提供的信息中获取 Keycloak 的
UserModel
,以识别用户。
Keycloak 具有默认提供程序。但是,管理员需要像这样设置身份验证通道提供程序
kc.[sh|bat] start --spi-ciba-auth-channel-ciba-http-auth-channel-http-authentication-channel-uri=https://backend.internal.example.com
可配置的项目及其描述如下。
配置 | 描述 |
---|---|
http-authentication-channel-uri |
指定实际通过 AD(身份验证设备)验证用户的实体的 URI。 |
身份验证通道提供程序
CIBA 标准文档未指定如何通过 AD 验证用户。因此,它可能根据产品的判断来实施。Keycloak 将此身份验证委托给外部身份验证实体。为了与身份验证实体通信,Keycloak 提供了身份验证通道提供程序。
Keycloak 的实现假定身份验证实体受 Keycloak 管理员的控制,以便 Keycloak 信任该身份验证实体。不建议使用 Keycloak 管理员无法控制的身份验证实体。
身份验证通道提供程序作为 SPI 提供程序提供,以便 Keycloak 用户可以实施自己的提供程序以满足其环境。Keycloak 提供了其默认提供程序,称为 HTTP 身份验证通道提供程序,该提供程序使用 HTTP 与身份验证实体进行通信。
如果 Keycloak 用户想要使用 HTTP 身份验证通道提供程序,他们需要了解 Keycloak 和身份验证实体之间的合同,该合同由以下两个部分组成。
- 身份验证委托请求/响应
-
Keycloak 向身份验证实体发送身份验证请求。
- 身份验证结果通知/确认
-
身份验证实体将身份验证结果通知给 Keycloak。
身份验证委托请求/响应由以下消息组成。
- 身份验证委托请求
-
该请求从 Keycloak 发送到身份验证实体,以请求其通过 AD 进行用户身份验证。
POST [delegation_reception]
-
标头
名称 | 值 | 描述 |
---|---|---|
Content-Type |
application/json |
消息体为 json 格式。 |
Authorization |
Bearer [token] |
[token] 在身份验证实体将身份验证结果通知给 Keycloak 时使用。 |
-
参数
类型 | 名称 | 描述 |
---|---|---|
路径 |
delegation_reception |
身份验证实体提供的用于接收委托请求的端点 |
-
主体
名称 | 描述 |
---|---|
login_hint |
它告诉身份验证实体谁通过 AD 进行了身份验证。 |
scope |
它告诉身份验证实体从经过身份验证的用户那里获得哪些 scope 的同意。 |
is_consent_required |
它显示身份验证实体是否需要获得经过身份验证的用户关于 scope 的同意。 |
binding_message |
其值旨在同时显示在 CD 和 AD 的 UI 中,以使用户认识到 AD 的身份验证是由 CD 触发的。 |
acr_values |
它告诉来自 CD 的请求身份验证上下文类引用。 |
- 身份验证委托响应
-
响应从身份验证实体返回到 Keycloak,以通知身份验证实体已收到来自 Keycloak 的身份验证请求。
-
响应
-
HTTP 状态代码 | 描述 |
---|---|
201 |
它通知 Keycloak 收到身份验证委托请求。 |
身份验证结果通知/确认由以下消息组成。
- 身份验证结果通知
-
身份验证实体将身份验证请求的结果发送到 Keycloak。
POST /realms/[realm]/protocol/openid-connect/ext/ciba/auth/callback
-
标头
名称 | 值 | 描述 |
---|---|---|
Content-Type |
application/json |
消息体为 json 格式。 |
Authorization |
Bearer [token] |
[token] 必须是身份验证实体在身份验证委托请求中从 Keycloak 收到的令牌。 |
-
参数
类型 | 名称 | 描述 |
---|---|---|
路径 |
realm |
Realm 名称 |
-
主体
名称 | 描述 |
---|---|
status |
它告诉通过 AD 进行用户身份验证的结果。 |
- 身份验证结果确认
-
响应从 Keycloak 返回到身份验证实体,以通知 Keycloak 已收到来自身份验证实体的用户身份验证结果。
-
响应
-
HTTP 状态代码 | 描述 |
---|---|
200 |
它通知身份验证实体收到身份验证结果的通知。 |
用户解析器提供程序
即使是同一用户,其表示形式在每个 CD、Keycloak 和身份验证实体中也可能有所不同。
为了使 CD、Keycloak 和身份验证实体识别同一用户,此用户解析器提供程序在它们之间转换其自身的用户表示形式。
用户解析器提供程序作为 SPI 提供程序提供,以便 Keycloak 用户可以实施自己的提供程序以满足其环境。Keycloak 提供了其默认提供程序,称为默认用户解析器提供程序,它具有以下特点。
-
仅支持
login_hint
参数,并用作默认值。 -
Keycloak 中的 UserModel 的
username
用于表示 CD、Keycloak 和身份验证实体上的用户。
OIDC 注销
OIDC 有四个与注销机制相关的规范
同样,由于所有这些都在 OIDC 规范中描述,因此我们在此处仅给出简要概述。
RP 发起的注销
这也是基于浏览器的注销,其中注销通过将用户重定向到 Keycloak 上的特定端点开始。当用户单击某些应用程序页面上的Log Out
链接时,通常会发生此重定向,该应用程序先前使用 Keycloak 对用户进行身份验证。
一旦用户被重定向到注销端点,Keycloak 将向客户端发送注销请求,以使它们使其本地用户会话无效,并可能在注销过程完成后将用户重定向到某个 URL。如果未使用 id_token_hint
参数,则可能会选择性地请求用户确认注销。注销后,只要提供了 post_logout_redirect_uri
作为参数,用户就会自动重定向到指定的 post_logout_redirect_uri
。请注意,如果包含 post_logout_redirect_uri
,则需要包含 client_id
或 id_token_hint
参数。此外,post_logout_redirect_uri
参数需要与客户端配置中指定的 Valid Post Logout Redirect URIs
之一匹配。
根据客户端配置,可以通过前端通道或后台通道将注销请求发送到客户端。对于依赖于上一节中描述的会话管理的前端浏览器客户端,Keycloak 不需要向它们发送任何注销请求;这些客户端会自动检测到浏览器中的 SSO 会话已注销。
前端通道注销
要配置客户端以通过前端通道接收注销请求,请查看前端通道注销客户端设置。使用此方法时,请考虑以下事项
-
Keycloak 发送到客户端的注销请求依赖于浏览器和为注销页面呈现的嵌入式
iframes
。 -
由于基于
iframes
,前端通道注销可能会受到内容安全策略 (CSP) 的影响,并且注销请求可能会被阻止。 -
如果用户在呈现注销页面之前或在实际将注销请求发送到客户端之前关闭浏览器,则他们在客户端的会话可能不会失效。
考虑使用后台通道注销,因为它提供了一种更可靠和安全的方法来注销用户并终止他们在客户端上的会话。 |
如果客户端未启用前端通道注销,则 Keycloak 将首先尝试通过后台通道使用后台通道注销 URL发送注销请求。如果未定义,服务器将回退到使用管理 URL。
Keycloak 服务器 OIDC URI 端点
以下是 Keycloak 发布的 OIDC 端点列表。当非 Keycloak 客户端适配器使用 OIDC 与身份验证服务器通信时,可以使用这些端点。它们都是相对 URL。URL 的根由 HTTP(S) 协议、主机名以及可选路径组成:例如
https://#:8080
- /realms/{realm-name}/protocol/openid-connect/auth
-
用于在授权码流程中获取临时代码,或使用隐式流程、直接许可或客户端许可获取令牌。
- /realms/{realm-name}/protocol/openid-connect/token
-
授权码流程用于将临时代码转换为令牌。
- /realms/{realm-name}/protocol/openid-connect/logout
-
用于执行注销。
- /realms/{realm-name}/protocol/openid-connect/userinfo
-
用于 OIDC 规范中描述的用户信息服务。
- /realms/{realm-name}/protocol/openid-connect/revoke
-
用于 RFC7009 中描述的 OAuth 2.0 令牌撤销。
- /realms/{realm-name}/protocol/openid-connect/certs
-
用于 JSON Web 密钥集 (JWKS),其中包含用于验证任何 JSON Web 令牌 (jwks_uri) 的公钥
- /realms/{realm-name}/protocol/openid-connect/auth/device
-
用于设备授权许可,以获取设备代码和用户代码。
- /realms/{realm-name}/protocol/openid-connect/ext/ciba/auth
-
这是客户端发起的后台通道身份验证许可的 URL 端点,用于获取 auth_req_id,该 ID 标识客户端发出的身份验证请求。
- /realms/{realm-name}/protocol/openid-connect/logout/backchannel-logout
-
这是用于执行 OIDC 规范中描述的后台通道注销的 URL 端点。
在所有这些中,将 {realm-name} 替换为 realm 的名称。
SAML
SAML 2.0 与 OIDC 类似,但更加成熟。它源于 SOAP 和 Web 服务消息规范,因此通常比 OIDC 更为冗长。SAML 2.0 是一种身份验证协议,用于在身份验证服务器和应用程序之间交换 XML 文档。XML 签名和加密用于验证请求和响应。
总的来说,SAML 实现了两种用例。
第一种用例是应用程序请求 Keycloak 服务器验证用户身份。成功登录后,应用程序将收到一个 XML 文档。该文档包含一个 SAML 断言,其中指定了用户属性。Realm 对文档进行数字签名,其中包含访问信息(例如用户角色映射),应用程序使用这些信息来确定用户被允许访问应用程序中的哪些资源。
第二种用例是客户端访问远程服务。客户端从 Keycloak 请求 SAML 断言,以代表用户调用远程服务。
SAML 绑定
Keycloak 支持三种绑定类型。
重定向绑定
重定向绑定使用一系列浏览器重定向 URI 来交换信息。
-
用户使用浏览器连接到应用程序。应用程序检测到用户未通过身份验证。
-
应用程序生成一个 XML 身份验证请求文档,并将其编码为 URI 中的查询参数。该 URI 用于重定向到 Keycloak 服务器。根据您的设置,应用程序还可以对 XML 文档进行数字签名,并将签名作为查询参数包含在重定向到 Keycloak 的 URI 中。此签名用于验证发送请求的客户端。
-
浏览器重定向到 Keycloak。
-
服务器提取 XML 身份验证请求文档,并验证数字签名(如果需要)。
-
用户输入其身份验证凭据。
-
身份验证后,服务器生成一个 XML 身份验证响应文档。该文档包含一个 SAML 断言,其中包含有关用户的元数据,包括姓名、地址、电子邮件以及用户拥有的任何角色映射。该文档通常使用 XML 签名进行数字签名,并且也可能被加密。
-
XML 身份验证响应文档被编码为重定向 URI 中的查询参数。该 URI 将浏览器带回应用程序。数字签名也作为查询参数包含在内。
-
应用程序接收重定向 URI 并提取 XML 文档。
-
应用程序验证 realm 的签名,以确保它收到有效的身份验证响应。SAML 断言中的信息用于做出访问决策或显示用户数据。
POST 绑定
POST 绑定与 重定向 绑定类似,但 POST 绑定使用 POST 请求而不是 GET 请求来交换 XML 文档。POST 绑定使用 JavaScript 使浏览器在交换文档时向 Keycloak 服务器或应用程序发送 POST 请求。HTTP 响应一个 HTML 文档,其中包含一个包含嵌入式 JavaScript 的 HTML 表单。当页面加载时,JavaScript 会自动调用该表单。
推荐使用 POST 绑定,原因在于以下两个限制:
-
安全性 — 使用 重定向 绑定时,SAML 响应是 URL 的一部分。由于可以在日志中捕获响应,因此安全性较低。
-
大小 — 在 HTTP 有效负载中发送文档比在有限的 URL 中为大量数据提供了更大的空间。
OpenID Connect 与 SAML 的比较
以下列出了一些在选择协议时需要考虑的因素。
对于大多数用途,Keycloak 建议使用 OIDC。
OIDC
-
OIDC 专门设计用于 Web。
-
OIDC 适用于 HTML5/JavaScript 应用程序,因为它比 SAML 更容易在客户端实现。
-
OIDC 令牌采用 JSON 格式,这使得 Javascript 更容易使用它们。
-
OIDC 具有使安全实施更轻松的功能。例如,请参阅规范用于确定用户登录状态的 iframe 技巧。
SAML
-
SAML 被设计为在 Web 之上工作的层。
-
SAML 可能比 OIDC 更为冗长。
-
用户选择 SAML 而不是 OIDC,因为人们普遍认为 SAML 更成熟。
-
用户选择 SAML 而不是 OIDC,因为现有应用程序已使用 SAML 进行安全保护。
Docker 注册表 v2 身份验证
Docker 身份验证默认情况下处于禁用状态。要启用 Docker 身份验证,请参阅《启用和禁用功能》指南。 |
Docker 注册表 V2 身份验证是一种协议,类似于 OIDC,用于针对 Docker 注册表验证用户身份。Keycloak 对此协议的实现使 Docker 客户端可以使用 Keycloak 身份验证服务器针对注册表进行身份验证。此协议使用标准令牌和签名机制,但它确实偏离了真正的 OIDC 实现。它的偏差在于为请求和响应使用了非常特定的 JSON 格式,并将存储库名称和权限映射到 OAuth 范围机制。
Docker 身份验证流程
身份验证流程在 Docker API 文档中进行了描述。以下是从 Keycloak 身份验证服务器的角度进行的摘要
-
执行
docker login
。 -
Docker 客户端从 Docker 注册表请求资源。如果资源受到保护且请求中没有身份验证令牌,则 Docker 注册表服务器会响应 401 HTTP 消息,其中包含有关所需权限和授权服务器位置的一些信息。
-
Docker 客户端基于 Docker 注册表的 401 HTTP 消息构建身份验证请求。客户端使用本地缓存的凭据(来自
docker login
命令)作为 HTTP 基本身份验证 请求的一部分发送到 Keycloak 身份验证服务器。 -
Keycloak 身份验证服务器尝试验证用户身份,并返回包含 OAuth 风格 Bearer 令牌的 JSON 正文。
-
Docker 客户端从 JSON 响应中接收到 bearer 令牌,并在授权标头中使用它来请求受保护的资源。
-
Docker 注册表接收到来自 Keycloak 服务器的带有令牌的对受保护资源的新请求。注册表验证令牌,并授予对请求资源的访问权限(如果适用)。
使用 Docker 协议成功进行身份验证后,Keycloak 不会创建浏览器 SSO 会话。浏览器 SSO 会话不使用 Docker 协议,因为它无法刷新令牌或从 Keycloak 服务器获取令牌或会话的状态;因此,浏览器 SSO 会话不是必需的。有关更多详细信息,请参阅“瞬态会话”部分。 |
管理对 realm 资源的访问
在 Keycloak 上创建的每个 realm 都有一个专用的管理控制台,可以从中管理该 realm。“master” realm 是一个特殊的 realm,允许管理员管理系统上的多个 realm。您还可以为不同 realm 中的用户定义细粒度的访问权限,以管理服务器。本章将介绍所有这些场景。
Master realm 访问控制
Keycloak 中的 master
realm 是一个特殊的 realm,与其他 realm 的处理方式不同。Keycloak master
realm 中的用户可以被授予管理部署在 Keycloak 服务器上的零个或多个 realm 的权限。创建 realm 时,Keycloak 会自动创建各种角色,这些角色授予访问该新 realm 的权限。可以通过将这些角色映射到 master
realm 中的用户来控制对管理控制台和管理 REST 端点的访问。可以创建多个超级用户,以及只能管理特定 realm 的用户。
全局角色
master
realm 中有两个 realm 级别的角色。它们是:
-
admin
-
create-realm
具有 admin
角色的用户是超级用户,并且拥有管理服务器上任何 realm 的完全访问权限。具有 create-realm
角色的用户被允许创建新的 realm。他们将被授予对其创建的任何新 realm 的完全访问权限。
Realm 特定角色
master
realm 中的管理员用户可以被授予对系统中一个或多个其他 realm 的管理权限。Keycloak 中的每个 realm 都由 master
realm 中的一个客户端表示。客户端的名称是 <realm name>-realm
。这些客户端各自定义了客户端级别的角色,这些角色定义了管理单个 realm 的不同级别的访问权限。
可用的角色包括:
-
create-client
-
impersonation
-
manage-authorization
-
manage-clients
-
manage-events
-
manage-identity-providers
-
manage-realm
-
manage-users
-
query-clients
-
query-groups
-
query-realms
-
query-users
-
view-authorization
-
view-clients
-
view-events
-
view-identity-providers
-
view-realm
-
view-users
将您想要的角色分配给您的用户,他们将只能使用管理控制台的特定部分。
具有 manage-users 角色的管理员将只能将他们自己拥有的管理员角色分配给用户。因此,如果管理员拥有 manage-users 角色但没有 manage-realm 角色,他们将无法分配 manage-realm 角色。 |
专用 realm 管理控制台
每个 realm 都有一个专用的管理控制台,可以通过访问 URL /admin/{realm-name}/console
来访问。可以通过分配特定的用户角色映射,向该 realm 中的用户授予 realm 管理权限。
每个 realm 都有一个名为 realm-management
的内置客户端。您可以通过转到 realm 的“客户端”左侧菜单项来查看此客户端。此客户端定义了客户端级别的角色,这些角色指定了可以授予的管理 realm 的权限。
-
create-client
-
impersonation
-
manage-authorization
-
manage-clients
-
manage-events
-
manage-identity-providers
-
manage-realm
-
manage-users
-
query-clients
-
query-groups
-
query-realms
-
query-users
-
realm-admin
-
view-authorization
-
view-clients
-
view-events
-
view-identity-providers
-
view-realm
-
view-users
将您想要的角色分配给您的用户,他们将只能使用管理控制台的特定部分。
使用权限委派 realm 管理
您可以使用细粒度管理员权限功能将域管理委派给其他管理员,即域管理员。与通过全局和域特定角色提供的基于角色的访问控制 (RBAC) 机制不同,此功能基于一组明确定义的可对其执行的操作,提供对如何访问和管理域资源更细粒度的控制。
通过依赖于基于策略的访问控制,服务器管理员可以使用不同的策略类型或访问控制方法来定义对域资源的权限,例如用户、组和客户端,以便将域管理员限制为仅访问域资源及其操作的子集。
此功能提供了上述 RBAC 机制的替代方案,但它不会取代它。您仍然可以授予管理角色,例如 view-users
或 manage-clients
,以委派对域管理员的访问权限,但这样做将跳过此功能提供的机制。
仅当通过管理控制台或 Admin API 管理资源时,才强制执行对域资源的访问。
了解域资源类型
在一个域中,您可以管理不同类型的资源,例如用户、组、客户端、客户端作用域、角色等等。作为域管理员,您在管理身份以及他们如何进行身份验证和授权以访问域和应用程序时,始终在管理这些资源。
此功能提供了必要的机制来强制执行在管理域资源时的访问控制,仅限于
-
用户
-
组
-
客户端
-
角色
您可以管理给定资源类型的所有资源的权限,例如域中的所有用户,或者管理特定域资源的权限,例如域中的特定用户或一组用户。
了解访问作用域
每个域资源都支持一组明确定义的管理操作或作用域,可以对其执行这些操作,例如 view
、manage
以及特定于资源的操作,例如 view-members
(如果您以组为例)。
管理权限时,您要从资源类型中选择一组或多个作用域,以允许域管理员对资源类型执行特定操作。例如,授予 view
作用域将使域管理员能够列出、搜索和查看域资源。另一方面,manage
作用域将允许管理员对其执行更新和删除操作。
这些作用域彼此完全独立。如果您授予 manage
域资源的访问权限,这并不意味着会自动授予 view
作用域。作用域之间不存在传递依赖关系。尽管这可能会影响管理权限时的整体用户体验,因为您需要选择单个作用域,但好处是您可以更轻松地识别强制执行对特定作用域访问的权限。
来自资源类型的某些作用域与来自另一个资源类型的作用域具有关系(不是传递依赖关系)。当您管理代表一组域资源的资源类型时,例如域组及其成员,这种关系主要是正确的。
用户资源类型
用户域资源类型表示域中的用户。您可以根据以下一组作用域管理用户的权限
作用域 | 描述 | 也通过以下方式授予 |
---|---|---|
view |
定义域管理员是否可以查看用户。每当您想要 |
|
manage |
定义域管理员是否可以管理用户。 |
|
manage-group-membership |
定义域管理员是否可以将用户分配到/从组中取消分配。 |
None |
map-roles |
定义域管理员是否可以将角色分配到/从用户取消分配。 |
None |
impersonate |
定义域管理员是否可以模拟其他用户。 |
|
用户资源类型与您可以为组设置的某些权限具有很强的关系。大多数时候,用户是组成员,并且授予对组的 view-members
或 manage-members
的访问权限也应该允许域管理员 view
和 manage
该组的成员。
此功能不支持强制执行对联合资源的访问,但是,未来改进正在考虑此限制。 |
组资源类型
组域资源类型表示域中的组。您可以根据以下一组管理操作管理组的权限
操作 | 描述 |
---|---|
view |
定义域管理员是否可以查看组。每当您想要使查询可以使用组时,都应设置此作用域。 |
manage |
定义域管理员是否可以管理组。 |
view-members |
定义域管理员是否可以查看组成员。此操作适用于组层次结构中的任何子组。可以通过显式拒绝特定子组的权限来阻止这种情况。 |
manage-members |
定义域管理员是否可以管理组成员。此操作适用于组层次结构中的任何子组。可以通过显式拒绝特定子组的权限来阻止这种情况。 |
impersonate-members |
定义域管理员是否可以模拟组成员。此操作适用于组层次结构中的任何子组。可以通过显式拒绝特定子组的权限来阻止这种情况。 |
manage-membership |
定义域管理员是否可以从组中添加或删除成员。 |
客户端资源类型
客户端域资源类型表示域中的客户端。您可以根据以下一组管理操作管理客户端的权限
操作 | 描述 |
---|---|
view |
定义域管理员是否可以查看客户端。每当您想要使查询可以使用客户端时,都应设置此作用域。 |
manage |
定义域管理员是否可以管理客户端。 |
map-roles |
定义域管理员是否可以将客户端定义的任何角色分配给用户。 |
map-roles-composite |
定义域管理员是否可以将客户端定义的任何角色作为复合角色分配给另一个角色。 |
map-roles-client-scope |
定义域管理员是否可以将客户端定义的任何角色分配给客户端作用域。 |
map-roles 操作不授予管理用户或任意分配角色的能力。管理员还必须具有用户的用户角色映射权限。
角色资源类型
角色域资源类型表示域中的角色。您可以根据以下一组管理操作管理角色的权限
操作 | 描述 |
---|---|
map-role |
定义域管理员是否可以将一个角色(或多个角色)分配给用户。 |
map-role-composite |
定义域管理员是否可以将一个角色(或多个角色)作为复合角色分配给另一个角色。 |
map-role-client-scope |
定义域管理员是否可以将一个角色(或多个角色)应用于客户端作用域。 |
map-roles 操作不授予管理用户或任意分配角色的能力。管理员还必须具有用户的用户角色映射权限。
如果客户端资源类型权限具有 map-roles、map-roles-composite 或 map-roles-client-scope 作用域,则如果角色是客户端角色,它将优先于任何角色资源类型权限。
为域启用管理员权限
要在域中启用细粒度管理员权限,请按照以下步骤操作
-
登录到管理控制台。
-
点击 Realm 设置。
-
启用 Admin Permissions 并单击 Save。
启用后,管理控制台的左侧菜单中会出现 Permissions 部分。
从此部分,您可以管理域资源的权限。
管理权限
Permissions 选项卡提供了域内所有活动权限的概述。从这里,管理员可以创建、更新、删除或搜索权限。您还可以预先评估您创建的权限,以检查它们是否按预期强制执行对域资源的访问。有关更多详细信息,请参阅评估权限。
要创建权限,请单击 Create permission
按钮并选择要保护的资源类型。
选择资源类型后,您现在可以定义应如何为所选类型的一个或多个资源集强制执行访问
管理权限时,您可以定义以下设置
-
名称:权限的唯一名称。该名称也不应与任何策略名称冲突
-
描述:可选描述,用于更好地描述权限的用途
-
授权作用域:一组或多个作用域,表示您要为所选资源类型保护的操作。管理员必须为每个操作分配显式权限才能执行相应的操作。例如,仅分配 manage 而不分配 view 将阻止用户可见。
-
强制访问:定义权限应强制访问所选类型的所有资源还是域中的特定资源。
-
策略:定义一组或多个策略,应评估这些策略以授予或拒绝访问所选资源。
创建权限后,它将在强制访问您选择的(所有)资源和作用域时自动生效。在生产环境中创建和更新权限时,请记住这一事实。
定义查看域资源的权限
此功能依赖于部分评估机制,以部分评估域管理员在列出和查看域资源时拥有的权限。此机制将预取为与查看相关的作用域设置的所有权限,其中直接或间接地引用了域管理员。
授予访问权限以 view
某种类型的域资源的权限必须使用以下策略之一,以使其可用于查询
-
用户
-
组
-
角色
通过使用上述任何策略,Keycloak 可以通过查找对域管理员的直接引用(如果使用用户策略)或间接引用(如果使用角色或组策略)来预先计算域管理员可以查看的资源集。因此,部分评估机制涉及使用将在数据库级别运行的访问控制来修饰查询。此功能主要对于正确允许分页资源以及避免在服务器端评估查询返回的每个域资源的权限时产生额外的开销非常重要。
仅当为域启用该功能,并且用户未被授予与查看相关的管理角色(例如 view-users
或 view-clients
)时,才会发生部分评估和过滤。例如,对于被授予 admin
角色的常规服务器管理员,它不会发生。
查询资源时,部分评估机制的工作方式如下
-
解析引用域管理员的特定资源类型的所有权限
-
预先评估每个权限,以检查域管理员是否具有对与该权限关联的资源的访问权限
-
根据授予或拒绝的资源修饰数据库查询
因此,查询的结果集将仅包含域管理员有权访问任何与查看相关的作用域的域资源。
搜索权限
Admin Console 提供了几种搜索权限的方法,支持以下功能
-
搜索在其 名称 中包含特定字符串的权限
-
搜索特定资源类型的权限,例如 用户
-
搜索应用于特定资源的特定资源类型的权限(例如用户
myadmin
的 用户 资源类型)。 -
搜索具有给定作用域的特定资源类型的权限(例如具有 manage 作用域的 用户 资源类型权限)。
-
搜索应用于特定资源且具有特定作用域的特定资源类型的权限(例如用户
myadmin
的具有 manage 作用域的 用户 资源类型权限)。
这些功能允许服务器管理员对其权限范围执行查询,并识别哪些权限正在强制执行对一组或多个域资源及其作用域的访问。结合 Evaluation 选项卡上的评估工具,它们为管理域中的权限提供了关键的管理工具。有关更多详细信息,请参阅评估权限。
管理策略
Policies 选项卡允许管理员使用不同的访问控制方法定义条件,以确定是否应将权限授予尝试对域资源执行操作的管理员。管理权限时,您必须至少关联一个策略才能授予或拒绝访问域资源。
策略基本上是评估为 GRANT
或 DENY
的条件。它们的结果将决定是否应授予或拒绝权限。
仅当其所有关联策略都评估为 GRANT
时,才授予权限。否则,权限将被拒绝,并且域管理员将无法访问受保护的资源。
Keycloak 提供了一组内置策略,您可以从中选择
一旦您为您的域定义了良好且稳定的权限模型,就几乎不需要创建策略。您可以改为重用现有策略来创建更多权限。
有关每种策略类型的更多详细信息,请参阅管理策略。
评估权限
Evaluation 选项卡提供了一个测试环境,管理员可以在其中验证权限是否按预期强制执行访问。管理员可以看到在强制访问特定资源时涉及哪些权限以及结果是什么。
您需要提供一组字段才能运行评估
-
用户
,域管理员或尝试访问资源的主体 -
资源类型
,您要评估的资源类型 -
资源选择器
,根据所选的资源类型
,系统将提示您选择特定的域资源,例如用户、组或客户端。 -
授权作用域
,您要评估的作用域或操作。如果未提供,则评估将针对所选资源类型的所有作用域进行。
通过单击 Evaluate
按钮,服务器将评估与所选资源和作用域关联的所有权限,就像所选 用户
在使用管理控制台或 Admin API 时尝试访问资源一样。
例如,在上面的示例中,您可以看到用户 myadmin
可以 manage 用户 user-1
,因为 Allow managing all realm users
权限投票为 PERMIT
,因此授予了对 manage
作用域的访问权限。但是,所有其他作用域都被拒绝。
结合 Permissions 选项卡中的搜索功能,您可以执行故障排除以识别任何未按预期运行的权限。
评估权限时,以下规则适用
-
特定于资源的权限的结果优先于授予对某种类型的所有资源访问权限的更广泛的权限
-
如果特定资源不存在权限,则将根据授予对某种类型的所有资源访问权限的权限来授予访问权限
-
强制访问特定资源的不同权限的结果仅当它们都允许访问该资源时才授予访问权限
解决冲突的权限
权限可以关联多个策略。随着授权模型的演进,权限内的一些策略,甚至与特定资源相关的不同权限之间,常常会发生冲突。
只要任何权限评估为“拒绝”,评估结果都将为“拒绝”。 如果存在与同一资源相关的多个权限,则所有权限都必须授予访问权限,结果才会是“授予”。
细粒度的管理员权限允许您为单个资源或资源类型本身(例如所有用户、所有组等)设置权限。 如果存在与特定资源相关的权限,则在评估期间将不考虑“所有资源”权限。 如果不存在特定权限,则回退到“所有资源”权限。 这种方法有助于解决以下场景:例如,允许 realm-admins 组的成员管理 realm 组成员,但阻止他们管理 realm-admins 组本身的成员。 |
以 Realm 管理员身份访问 Realm 管理控制台
Realm 管理员可以访问专用的 realm 特定管理控制台,该控制台允许他们管理其分配的 realm 内的资源。 此控制台与主 Keycloak 管理控制台分开,后者通常由服务器管理员使用。
有关专用 realm 管理控制台和可用角色的更多详细信息,请参阅: 专用管理控制台。
要访问管理控制台,realm 管理员必须至少分配有以下角色之一,具体取决于他们需要管理的资源
-
query-users – 查询 realm 用户是必需的。
-
query-groups – 查询 realm 组是必需的。
-
query-clients – 查询 realm 客户端是必需的。
通过向 realm 用户授予任何这些角色,他们将能够访问管理控制台,但仅限于与授予的角色对应的区域。 例如,如果您分配 query-users
角色,则 realm 管理员将只能访问管理控制台中的“用户
”部分。 如果管理员负责多种资源类型(例如用户和组),他们必须分配所有相应的“query-*”角色。
这些角色启用对查询资源的基本访问权限,但不授予查看或修改它们的权限。 要授予或拒绝访问 realm 资源,您需要为每种资源类型提供的任何操作设置权限。 有关更多详细信息,请参阅管理权限。
角色和权限关系
细粒度权限用于授予额外的权限。 您无法覆盖内置管理员角色的默认行为。 如果向 realm 管理员分配了一个或多个管理员角色,则会阻止评估权限。 这意味着,如果向 realm 管理员分配了相应的管理员角色,则将绕过权限评估,并授予访问权限。
管理员角色 | 描述 |
---|---|
query-users |
realm 管理员可以在管理控制台中看到“用户”部分,并且可以在 realm 中搜索用户。 这不授予查看用户的能力。 |
query-groups |
realm 管理员可以在管理控制台中看到“组”部分,并且可以在 realm 中搜索组。 这不授予查看组的能力。 |
query-clients |
realm 管理员可以在管理控制台中看到“客户端”部分,并且可以在 realm 中搜索客户端。 这不授予查看客户端的能力。 |
view-users |
realm 管理员可以查看 realm 中的所有用户和组。 |
manage-users |
realm 管理员可以查看、map-roles、manage-group-membership 和 manage realm 中的所有用户,以及查看、manage-membership 和 manage realm 中的组。 |
impersonation |
realm 管理员可以模拟 realm 中的所有用户。 |
view-clients |
realm 管理员可以查看 realm 中的所有客户端。 |
manage-clients |
realm 管理员可以查看和 manage realm 中的所有客户端和客户端作用域。 |
理解一些常见的用例
考虑这样一种情况:管理员想要允许一组管理员管理 realm 中的所有用户,但属于管理员组的用户除外。 此示例包括一个 test
realm 和一个 test-admins
组。
允许管理员组管理用户
创建用户权限,允许 test-admins
组的成员查看和管理 realm 中的所有用户
-
导航到管理控制台中的“权限”选项卡。
-
单击“创建权限”,然后选择“用户”资源类型。
-
填写名称,例如
禁止管理 test-admins
。 -
选择 view 和 manage 授权范围,保持选中“所有用户”。
-
创建一个条件,需要满足该条件才能获得访问权限,方法是单击“创建新策略”。
-
填写名称
允许 test-admins
,选择“组”作为“策略类型”。 -
单击“添加组”按钮,选择
test-admins
组,单击“保存”。 -
在“创建权限”页面上单击“保存”。
允许管理员组管理用户,但不包括组成员
让我们排除组成员本身,以便 test-admins
无法管理其他管理员。
-
单击“创建权限”创建新权限。
-
这次选择“组”资源类型。
-
填写名称,例如
禁止管理 test-admins
。 -
选择 manage-members 授权范围。
-
选择“特定组”,然后选择
test-admins
组。 -
创建新策略,类型为“组”。
-
填写名称
禁止 test-admins
,然后选择test-admins
组。 -
切换策略的“否定逻辑”,保存策略
-
保存权限
允许具有特定角色的组成员模拟用户
-
为您要允许模拟的特定用户(或所有用户)创建“用户权限”。
-
创建“组策略”,允许访问
test-admins
的成员。 -
创建“角色策略”,允许访问分配了
impersonation-admin
角色的用户。 -
将这两个策略分配给权限。
允许具有特定角色的管理员查看用户,但不管理用户
-
为所有用户创建具有 view 范围的“用户权限”。
-
创建“角色策略”,允许访问具有特定角色的用户。
-
不要分配
manage
范围,以防止修改用户详细信息。
性能注意事项
在 realm 中启用此功能时,当 realm 管理员管理任何受支持的资源类型时,都会产生额外的开销。 当执行以下操作时,尤其如此
-
列出和搜索
-
更新或删除
每当您列出或管理 realm 资源时,该功能都会引入额外的检查,以便根据您定义的权限强制执行访问。 当查询 realm 资源时,尤其如此,因为部分评估 realm 管理员的权限以过滤和分页结果会产生额外的开销。
引用 realm 管理员用户及其可以访问的大多数资源的权限越少越好。 例如,如果您想委派对 realm 管理员的访问权限以管理用户,最好将这些用户作为组成员。 这样做不仅可以提高评估权限时的性能,还可以创建一个更易于管理的权限模型。
访问强制执行的主要影响是在查询 realm 资源时。 例如,如果 realm 管理员通过用户、角色或组策略在数千个权限中被引用,则在查询 realm 资源时发生的部分评估机制将从数据库中查询所有这些权限。 更简洁和优化的模型将有助于获取更少的权限,但足以授予或拒绝访问 realm 资源。
例如,使用组权限授予 realm 管理员查看和管理 realm 中用户的权限比为 realm 中的每个用户创建单独的权限更好。 并且确保与权限关联的策略(通过直接引用(用户策略)或间接引用(角色或组策略)引用 realm 管理员)不会跨越多个(数千个)权限,而与资源类型无关。
例如,假设您的 realm 中有三个用户,您想允许 realm 管理员 bob
view
和 manage
他们。 非最优的权限模型将为每个用户创建三个不同的权限,其中用户策略授予 bob
访问权限。 相反,您可以拥有单个组权限,甚至单个用户权限,将这三个用户分组,同时仍然使用相同的用户策略授予 bob
访问权限。
如果您想向更多 realm 管理员授予对这三个用户的访问权限,情况也是如此。 您可以考虑使用组策略或角色策略,而不是创建单独的策略。 权限模型是特定于用例的,但这些建议对于不仅提供更好的可管理性,而且还提高服务器在管理 realm 资源时的整体性能非常重要。
在服务器配置方面,根据 realm 的大小以及您拥有的权限和策略的数量,您可能需要考虑更改缓存配置以增加以下缓存的大小
-
域
-
用户
-
授权
考虑查看这些缓存的服务器指标,以找到调整部署大小的最佳值。
在过滤资源时,部分评估机制最终将依赖 SQL 语句中的 IN
子句来过滤结果。 根据您的数据库,您可能对 IN
子句的参数数量有限制。 Oracle 数据库的旧版本就是这种情况,它对参数数量有 1000 个的硬性限制。 为了避免此类问题,请记住上面关于授予或拒绝访问单个 realm 管理员的权限数量的注意事项。
细粒度管理员权限 V1
细粒度管理员权限 V1 已被新版本取代。 该功能的版本 1 仍标记为预览版并且可用,但将来可能会被弃用和删除。 要启用它,请使用 --features=admin-fine-grained-authz:v1 启动服务器。 |
有时,像 manage-realm
或 manage-users
这样的角色粒度太粗,您想要创建具有更细粒度权限的受限管理员帐户。 Keycloak 允许您为管理 realm 定义和分配受限访问策略。 诸如
-
管理一个特定客户端
-
管理属于特定组的用户
-
管理组成员资格
-
有限的用户管理。
-
细粒度的模拟控制
-
能够为用户分配一组特定的受限角色。
-
能够为复合角色分配一组特定的受限角色。
-
能够为客户端的作用域分配一组特定的受限角色。
-
用于查看和管理用户、组、角色和客户端的新通用策略。
关于细粒度管理员权限,有一些重要事项需要注意
管理一个特定的客户端
我们首先来看一下如何允许管理员仅管理一个客户端。在我们的示例中,我们有一个名为 test
的 realm 和一个名为 sales-application
的客户端。在 test
realm 中,我们将授予该 realm 中的用户仅管理该应用程序的权限。
您无法进行跨 realm 的细粒度权限控制。master realm 中的管理员仅限于前面章节中定义的预定义管理员角色。 |
权限设置
我们首先要做的是登录到管理控制台,以便为该客户端设置权限。我们导航到要定义细粒度权限的客户端的管理部分。
您应该看到一个名为 Permissions
的标签菜单项。点击该标签。
默认情况下,每个客户端都未启用细粒度权限。因此,请将 Permissions Enabled
开关切换到“开”以初始化权限。
如果您将 Permissions Enabled 开关切换到“关”,它将删除您为该客户端定义的所有权限。 |
当您将 Permissions Enabled
开关切换到“开”时,它会在后台使用 Authorization Services 初始化各种权限对象。对于本示例,我们对客户端的 manage
权限感兴趣。点击它会将您重定向到处理客户端 manage
权限的权限页面。所有授权对象都包含在 realm-management
客户端的 Authorization
标签中。
首次初始化时,manage
权限没有任何关联的策略。您需要通过转到策略标签来创建一个。要快速到达那里,请点击上图所示的 Client details
链接。然后点击策略标签。
在此页面上,找到 Create client policy
按钮,您可以使用它来定义许多策略。您可以定义与角色或组关联的策略,甚至可以在 JavaScript 中定义规则。对于这个简单的示例,我们将创建一个 User Policy
。
此策略将匹配用户数据库中的硬编码用户。在本例中,它是 sales-admin
用户。然后我们必须返回到 sales-application
客户端的 manage
权限页面,并将该策略分配给权限对象。
sales-admin
用户现在有权管理 sales-application
客户端。
还有一件事我们必须做。转到 Users
,选择 sales-admin
用户,然后转到 Role Mappings
标签,并将 query-clients
角色分配给该用户。
为什么您必须这样做?此角色告诉管理控制台当 sales-admin
访问管理控制台时要呈现哪些菜单项。query-clients
角色告诉管理控制台,它应该为 sales-admin
用户呈现客户端菜单。
重要提示:如果您不设置 query-clients
角色,像 sales-admin
这样的受限管理员在登录到管理控制台时将看不到任何菜单选项。
测试一下
接下来,我们从 master realm 登出,然后使用 sales-admin
作为用户名重新登录到 test
realm 的 专用管理控制台。它位于 /admin/test/console
下。
此管理员现在能够管理这一个客户端。
限制用户角色映射
您可能想要做的另一件事是限制管理员可以分配给用户的角色集。继续我们的上一个示例,让我们扩展 'sales-admin' 用户的权限集,以便他还可以控制哪些用户可以访问此应用程序。通过细粒度权限,我们可以启用它,以便 sales-admin
只能分配授予对 sales-application
特定访问权限的角色。我们还可以限制管理员只能映射角色,而不能执行任何其他类型的用户管理。
sales-application
定义了三个不同的客户端角色。
我们希望 sales-admin
用户能够将这些角色映射到系统中的任何用户。执行此操作的第一步是允许管理员映射该角色。如果我们点击 viewLeads
角色,您将看到此角色有一个 Permissions
标签。
如果我们点击该标签并将 Permissions Enabled
切换为“开”,您将看到我们可以将策略应用于许多操作。
我们感兴趣的是 map-role
。点击此权限并添加在前面示例中创建的相同用户策略。
我们所做的是声明 sales-admin
可以映射 viewLeads
角色。我们尚未做的是指定管理员允许将此角色映射到哪些用户。为此,我们必须转到此 realm 的管理控制台的 Users
部分。点击左侧菜单项 Users
会将我们带到 realm 的用户界面。您应该看到一个 Permissions
标签。点击它并启用它。
我们感兴趣的权限是 map-roles
。这是一个限制性策略,因为它仅允许管理员将角色映射到用户。如果我们点击 map-roles
权限并再次添加为此创建的用户策略,我们的 sales-admin
将能够将角色映射到任何用户。
我们要做的最后一件事是将 view-users
角色添加到 sales-admin
。这将允许管理员查看他想要向其添加 sales-application
角色的 realm 中的用户。
测试一下
接下来,我们从 master realm 登出,然后使用 sales-admin
作为用户名重新登录到 test
realm 的 专用管理控制台。它位于 /admin/test/console
下。
您将看到现在 sales-admin
可以查看系统中的用户。如果您选择其中一个用户,您将看到每个用户详细信息页面都是只读的,除了 Role Mappings
标签。转到此标签,您会发现除了浏览 sales-application
角色之外,管理员没有 Available
角色可以映射到用户。
我们仅指定了 sales-admin
可以映射 viewLeads
角色。
完整的权限列表
除了管理特定客户端或客户端的特定角色之外,您还可以使用细粒度权限做更多的事情。本章定义了可以为 realm 描述的完整权限类型列表。
角色
当转到特定角色的 Permissions
标签时,您将看到列出的这些权限类型。
- map-role
-
决定管理员是否可以将此角色映射到用户的策略。这些策略仅指定可以将角色映射到用户,而不是管理员被允许执行用户角色映射任务。管理员还必须具有管理或角色映射权限。有关更多信息,请参阅 用户权限。
- map-role-composite
-
决定管理员是否可以将此角色作为复合角色映射到另一个角色的策略。如果管理员必须管理客户端的权限,则可以为客户端定义角色,但他将无法向这些角色添加复合角色,除非他拥有要添加为复合角色的
map-role-composite
权限。 - map-role-client-scope
-
决定管理员是否可以将此角色应用于客户端范围的策略。即使管理员可以管理客户端,除非授予此权限,否则他也没有权限为该客户端创建包含此角色的令牌。
客户端
当转到特定客户端的 Permissions
标签时,您将看到列出的这些权限类型。
- view
-
决定管理员是否可以查看客户端配置的策略。
- manage
-
决定管理员是否可以查看和管理客户端配置的策略。这里存在一些问题,即权限可能会被意外泄露。例如,即使管理员没有权限将角色映射到客户端范围,管理员也可以定义一个硬编码角色的协议映射器。这是当前协议映射器的局限性,因为它们没有像角色那样为它们分配单独权限的方法。
- 配置
-
用于管理客户端的减少的权限集。它类似于
manage
范围,但管理员不允许定义协议映射器、更改客户端模板或客户端范围。 - map-roles
-
决定管理员是否可以将客户端定义的任何角色映射到用户的策略。这是一个快捷方式,易于使用的功能,避免了必须为客户端定义的每个角色定义策略。
- map-roles-composite
-
决定管理员是否可以将客户端定义的任何角色作为复合角色映射到另一个角色的策略。这是一个快捷方式,易于使用的功能,避免了必须为客户端定义的每个角色定义策略。
- map-roles-client-scope
-
决定管理员是否可以将客户端定义的任何角色映射到另一个客户端范围的策略。这是一个快捷方式,易于使用的功能,避免了必须为客户端定义的每个角色定义策略。
用户
当转到所有用户的 Permissions
标签时,您将看到列出的这些权限类型。
- view
-
决定管理员是否可以查看 realm 中所有用户的策略。
- manage
-
决定管理员是否可以管理 realm 中所有用户的策略。此权限授予管理员执行用户角色映射的权限,但它没有指定管理员允许映射哪些角色。您需要为您希望管理员能够映射的每个角色定义权限。
- map-roles
-
这是
manage
范围授予的权限的子集。在本例中,管理员仅被允许映射角色。管理员不允许执行任何其他用户管理操作。此外,与manage
一样,管理员允许应用的 roles 必须按角色或按角色集(如果处理客户端角色)指定。 - manage-group-membership
-
类似于
map-roles
,不同之处在于它与组成员身份有关:用户可以添加到哪些组或从哪些组中删除。这些策略仅授予管理员管理组成员身份的权限,而不是管理员允许管理哪些组的成员身份。您必须为每个组的manage-members
权限指定策略。 - impersonate
-
决定是否允许管理员模拟其他用户的策略。这些策略应用于管理员的属性和角色映射。
- 用户模拟
-
决定哪些用户可以被模拟的策略。这些策略将应用于被模拟的用户。例如,您可能想要定义一个策略,禁止任何人模拟具有管理员权限的用户。
管理组织
当与客户或业务合作伙伴等第三方集成时,您可能希望将其身份与其他身份分开管理,并在他们与 realm 交互时,在整个业务生态系统中构建统一且安全的体验。
在 realm 中,组织代表这些第三方,以便 realm 或组织管理员可以按组织管理其成员的整个生命周期以及他们如何对 realm 进行身份验证和授权。
组织是开始使用 Keycloak 的 IAM 功能来解决企业对企业 (B2B) 用例的入口点。它在 realm 中启用多租户,以便用户可以访问 realm 中的受保护资源,但在更受限和受控的上下文中,该上下文是他们所属的组织。
Keycloak Organizations 是一项在 Keycloak 中启用组织支持的功能。目前,它提供了一些管理组织所需的核心功能,例如
-
管理成员
-
使用邀请链接加入组织成员
-
通过身份代理联合其身份来加入组织成员
-
在组织范围内进行身份验证时的身份优先登录和组织特定步骤
-
通过令牌将组织特定的声明传播到应用程序以用于授权目的
在 Keycloak 中启用组织
要使用组织,您必须为当前 realm 启用此功能。
-
在菜单中单击“Realm 设置”。
-
将 组织 切换为 开启。
-
点击 保存
一旦启用该功能,您就可以通过菜单中可用的 组织 部分管理组织。
管理组织
从 组织 部分,您可以管理 realm 中的所有组织。
创建组织
-
点击 创建组织。
组织具有以下设置
- 名称
-
组织的易于理解的名称。该名称在 realm 内是唯一的。
- 别名
-
此组织的别名,用于在内部引用组织。别名在 realm 内是唯一的,并且必须是 URL 友好的,因此通常在 URL 中不允许的字符将不被允许在别名中使用。如果未设置,Keycloak 将尝试使用名称作为别名。如果名称不是 URL 友好的,您将收到错误,并且将被要求指定别名。一旦定义,别名之后就无法更改。
- 重定向 URL
-
在完成注册或接受通过电子邮件发送的组织邀请后,用户将自动重定向到指定的重定向 URL。如果留空,用户默认将被重定向到帐户控制台。
- 域名
-
属于此组织的一个或多个域名的集合。域名不能在 realm 内的不同组织之间共享。
- 描述
-
描述组织的自由文本字段。
创建组织后,您可以管理以下部分中描述的其他设置
理解组织域名
在管理组织时,与组织关联的域名在组织成员如何向 realm 验证身份以及如何验证其配置文件方面起着重要作用。
域名的一个关键作用是帮助识别用户所属的组织。通过查看用户的电子邮件地址,Keycloak 将使用相同的域名匹配相应的组织,并最终根据组织的要求更改身份验证流程。
域名还允许组织强制用户在其电子邮件中不允许使用与其组织关联的域名以外的域名。当用户及其身份从与组织关联的身份提供商联合而来,并且您想为他们的电子邮件地址强制使用特定的电子邮件域名时,此限制尤其有用。
禁用组织
要禁用组织,请将 已启用 切换为 关闭。
当组织被禁用时,您仍然可以通过管理界面管理它,但是组织成员无法向 realm 验证身份,包括通过与组织关联的身份提供商进行身份验证,因为它们也会自动被禁用。
但是,组织的非托管成员仍然能够向 realm 验证身份,因为他们也是 realm 用户,但是令牌将不包含有关他们与已禁用组织的关系的元数据。
有关托管和非托管用户的更多详细信息,请参阅 托管和非托管成员 部分。
删除组织
要删除组织,请在列表页面或编辑组织时,单击相应组织的 删除 操作。
删除组织时,将删除与其关联的所有数据,包括任何托管成员。
非托管用户和身份提供商保留在 realm 中,但它们不再链接到该组织。
有关托管和非托管用户的更多详细信息,请参阅 托管和非托管成员。
管理属性
管理员可以使用属性存储有关组织的附加元数据。组织属性是一个键/值对,可以保存多个字符串值。
为此,请单击 属性 选项卡,并通过提供键和值来设置您想要的任何属性。
要为同一属性和键提供多个值,只需添加另一个具有相同键但值不同的属性即可。
管理成员
组织成员基本上是 realm 用户,但链接到单个组织。它们在逻辑上与 realm 中的其他用户分开,以便您确切地知道哪些用户属于组织。
有不同的方法可以将成员添加到组织或让成员加入组织
-
添加现有域用户作为成员
-
通过与组织关联的身份提供商
-
发送邀请以创建新帐户
-
发送邀请给现有用户以加入组织
一旦成为组织成员,就可以像管理 realm 中的任何常规帐户一样管理该用户的帐户,方法是访问菜单中的 用户 部分。
但是,您可以通过访问管理组织时的 成员 选项卡,将用户范围缩小到仅与组织关联的用户。在此选项卡中,您可以看到所有组织成员的列表,以及添加新成员以及编辑和删除现有成员的操作。
托管和非托管成员
在管理成员时,请考虑他们与组织的关系如何影响其帐户的生命周期。成员可以通过不同的流程加入组织,每个流程都表明其帐户与组织之间链接的强度。
有两种类型的成员
-
托管
-
非托管
托管成员是由组织管理的成员,他们不能在其组织之外存在。例如,考虑通过与组织关联的身份提供商创建的帐户。该帐户不属于 realm,因为它来自组织联合身份验证。在这种情况下,身份的单一来源是组织,其生命周期由组织控制。如果删除组织或成员,则该帐户也会从 realm 中删除。
另一方面,非托管成员是那些可以脱离组织而存在的成员。例如,当将现有 realm 用户添加到组织时,该帐户首先属于 realm,然后最终链接到组织。在这种情况下,删除组织或成员不会从 realm 中删除该帐户;realm 是身份的单一来源。
将现有 realm 用户添加为成员
现有 realm 用户可以通过从列表中选择该用户并将该用户添加到组织来加入组织。
-
点击 添加成员。
-
点击 添加 realm 用户。
-
选择一个或多个用户,然后点击 添加 以将他们添加到组织。
一旦用户成为组织成员,该用户就可以像常规用户一样向 realm 验证身份,并使用 realm 支持的任何凭据。
邀请用户
管理员可以发送电子邮件邀请用户加入组织。
-
点击 添加成员。
-
点击 邀请成员。
-
提供电子邮件地址
-
点击 发送
可选地,您还可以为 名字 和 姓氏 字段提供值,以便使用包含接收电子邮件的人的名字和姓氏的问候消息,使电子邮件消息更加个性化。
邀请基本上是发送一封电子邮件,其中包含一个链接,用户应单击该链接以执行加入组织所需的步骤。这些步骤取决于该人员是否已经在 realm 中拥有帐户,或者是否应在加入组织之前创建新帐户。
如果该电子邮件映射到 realm 中的现有用户,则用户将遵循的步骤基本上是确认加入组织的意图。
另一方面,如果没有用户与给定的电子邮件地址关联,则步骤将涉及通过 realm 的自助注册流程创建新帐户。在这种情况下,用户将被强制提供用于发送邀请的相同电子邮件地址。
使用身份提供商引导成员加入
组织可能拥有自己的身份提供商作为其身份的单一来源。在这种情况下,从身份提供商联合身份验证的用户将自动添加为组织成员。
当用户通过与组织关联的身份提供商加入组织时,他们会自动标记为托管成员。在这种情况下,他们将经历 realm 中配置的代理登录流程,并在成功验证身份后自动加入组织。
通过身份提供商引导新成员加入可以通过自动将用户重定向到组织的身份提供商或在登录页面选择身份提供商来完成。
在这两种情况下,一旦用户提供电子邮件,Keycloak 将尝试根据电子邮件域名匹配组织。如果电子邮件域名与组织匹配,并且身份提供商与同一域名关联,并且 当电子邮件域名匹配时重定向 设置已启用,则用户将自动重定向到身份提供商。一旦用户在身份提供商处验证身份并完成第一个代理登录流程,用户将自动添加为组织成员。
另一方面,如果 当电子邮件域名匹配时重定向 未启用,但身份提供商配置为不 在登录页面隐藏,则用户可以选择身份提供商,然后重定向到身份提供商以继续引导加入流程。
有关更多详细信息,请参阅 管理身份提供商。
移除成员
您可以从组织中移除成员。
从您要移除的成员旁边的操作菜单中,单击 移除。
从组织中移除成员时,请记住,用户是否会从 realm 中移除取决于该用户是托管成员还是非托管成员。
有关更多详细信息,请参阅 托管和非托管成员。
管理身份提供商
组织可能拥有自己的身份提供商作为其身份的单一来源。在这种情况下,您需要配置组织以使用组织的身份提供商验证用户身份,联合身份验证他们的身份,并最终将他们添加为组织成员。
组织可以关联一个或多个身份提供商,以便他们可以从不同的来源验证其用户,并对每个来源强制执行不同的约束。
在将身份提供商链接到组织之前,您需要从菜单中的身份提供商部分在 realm 级别创建一个组织。您可以将 realm 中可用的任何内置社交和身份提供商链接到组织。
将身份提供商链接到组织
可以从身份提供商选项卡将身份提供商链接到组织。如果身份提供商已存在,您将看到它们的列表以及搜索、编辑或从组织取消链接的选项。
-
单击链接身份提供商
-
选择一个身份提供商
-
设置适当的设置
-
点击 保存
身份提供商具有以下设置
- 身份提供商
-
您要链接到组织的身份提供商。一个身份提供商只能链接到一个组织。
- 域名
-
您要与身份提供商链接的组织域名。
- 在登录页面隐藏
-
如果当用户在组织范围内进行身份验证时,应在登录页面中隐藏此身份提供商。
- 当电子邮件域名匹配时重定向
-
当成员的电子邮件域名与为身份提供商设置的域名匹配时,是否应自动重定向到身份提供商。如果域名设置为
Any
,则电子邮件域名与任何组织域名匹配的成员将被重定向到身份提供商。
如果组织链接了多个身份提供商,则组织验证器会优先选择与用户电子邮件域名匹配的提供商进行自动重定向。如果找不到,它会尝试查找域名设置为 Any
的提供商。
一旦链接到组织,就可以像在 realm 中管理任何其他提供商一样管理身份提供商,只需访问菜单中的身份提供商部分即可。但是,本文描述的选项仅在组织范围内管理身份提供商时可用。唯一的例外是为方便起见在此处提供的在登录页面隐藏选项。
验证成员身份
当您为 realm 启用组织时,用户身份验证会发生更改。如果用户被识别为在组织的上下文中进行身份验证,则身份验证流程会根据每个组织而变化。
创建 realm 时,身份验证流程会自动更新,以启用特定步骤来验证组织成员身份和引导组织成员。更新的身份验证流程包括
-
浏览器
-
首次代理登录
浏览器流程的主要更改是,它默认使用身份优先登录,以便在提示用户输入凭据之前识别用户。关于首次代理登录流程,主要更改是在用户通过与组织关联的身份提供商进行身份验证并成功完成流程后,自动将用户添加为组织成员。
是否选择使用身份优先登录取决于 realm 中是否存在组织。如果不存在组织,用户将按照通常的步骤,使用用户名和密码或在浏览器流程中配置的任何其他步骤进行身份验证。否则,系统会首先要求用户提供用户名或电子邮件,以便继续对 realm 进行身份验证。
身份优先登录的主要目标是识别用户
-
用户是现有用户还是新用户?
-
用户是否是 realm 内任何组织的成员?
-
如果是组织成员,用户是否链接到与组织关联的任何身份提供商?
根据识别用户的结果,身份验证流程会更改为继续进行身份验证(要求用户提供凭据),或者最终自动重定向用户,以便通过身份提供商在组织安全边界内进行身份验证。
了解身份优先登录
除了在提供用户名后识别用户之外,身份优先登录还负责
-
将电子邮件域名与组织匹配。
-
如果提供的用户名已存在帐户,则决定是否应继续身份验证流程
-
根据域名和身份提供商如何配置到组织,决定用户应如何进行身份验证
-
如果电子邮件域名与为身份提供商设置的域名匹配,则通过与组织关联的身份提供商无缝验证用户身份
身份优先登录提供与通常的登录页面(带有用户名和密码字段)相同的功能。用户仍然可以通过单击注册链接进行自助注册,或者选择未链接到该 realm 中组织的任何身份或社交代理。
如果用户不存在,并且该用户尝试使用与组织域名匹配的电子邮件域名进行身份验证,则身份优先登录页面将再次出现,并显示一条消息,指出提供的用户名无效。此时,无需再要求用户提供凭据。
有几种选项可用于注册用户,允许该用户验证 realm 身份并加入组织。
如果 realm 启用了自助注册设置,则用户可以单击身份优先登录页面上的注册链接,并在 realm 创建一个帐户。之后,管理员可以向用户发送邀请链接,或者手动将用户添加为组织成员。有关更多详细信息,请参阅管理成员。
如果组织具有没有域名的身份提供商,并且在登录页面隐藏设置为关闭,则用户还可以单击身份优先登录页面上的身份提供商链接,以自动创建一个帐户并在通过身份提供商进行身份验证后加入组织。有关更多详细信息,请参阅管理身份提供商。
在与上一节类似的情况下,组织可能已设置了具有组织域名之一的身份提供商。在这种情况下,如果用户的电子邮件与组织的特定域名匹配,则用户将被重定向到身份提供商。流程完成后,将创建一个帐户,并且用户加入组织。
配置现有身份验证流程
如前所述,对于新的 realm,身份验证流程会自动更新必要的步骤,以支持组织并验证其成员身份。对于现有 realm,除了为 realm 启用组织之外,您还需要手动更新现有的(自定义)身份验证流程。
通过以下步骤更改 browser 流程
-
复制绑定到 Browser flow 绑定类型的当前流程,以避免破坏您当前正在使用的流程
-
单击添加子流程并为其命名,例如 我的组织
-
将新添加的 我的组织 子流程移动到紧接在 身份提供商重定向器 执行步骤之后执行。这里的重点是,子流程应在任何其他子流程或执行步骤之前发生,这些子流程或执行步骤使用您在 realm 中支持的任何凭据来验证用户身份。添加后,将 要求 更改为 备选。
-
在 我的组织 子流程中单击添加子流程,并为其命名,例如 我的组织 - 条件式。添加后,将 要求 更改为 条件式。
-
在 我的组织 - 条件式 子流程中单击添加条件,然后选择 条件 - 用户已配置。添加后,将 要求 更改为 必需。
-
在 我的组织 - 条件式 子流程中单击添加步骤,然后选择 *组织身份优先登录
-
执行步骤。添加后,将 要求 更改为 备选。
-
-
将身份验证流程绑定到 Browser 绑定类型。
一旦您为 realm 启用组织设置并至少创建一个组织,您应该能够看到身份优先登录页面并开始在 realm 中使用组织。
通过以下步骤更改 first broker login 流程
-
复制绑定到 First broker login flow 绑定类型的当前流程,以避免破坏您当前正在使用的流程
-
单击添加子流程并为其命名,例如
组织成员 - 条件式
。添加后,将 要求 更改为 条件式。 -
在 组织成员 - 条件式 子流程中单击添加条件,然后选择 条件 - 用户已配置。添加后,将 要求 更改为 必需。
-
在 组织成员 - 条件式 子流程中单击添加步骤,然后选择 组织成员入职 执行步骤。添加后,将 要求 更改为 必需。
-
将身份验证流程绑定到 First broker login 绑定类型。
现在,您应该能够使用与组织关联的任何身份提供商进行身份验证,并在用户完成首次浏览器登录流程后立即加入组织成为成员。
配置用户身份验证方式
如果流程支持组织,您可以配置某些步骤来更改用户对 realm 进行身份验证的方式。
例如,某些用例将要求用户仅当他们是 realm 中任何组织或特定组织的成员时才对 realm 进行身份验证。
要启用此行为,您需要在 组织身份优先登录
执行步骤上启用 需要用户成员资格
设置,方法是单击其设置。
如果启用,并且在用户在身份优先登录页面中提供用户名或电子邮件后,服务器将尝试解析用户是其成员的组织,方法是查找任何现有成员资格或基于客户端请求的 组织 范围的语义。如果不是组织成员,则会显示错误页面。
映射组织声明
要将组织特定的声明映射到令牌中,客户端需要在向服务器发送授权请求时请求 organization 范围。当在组织的上下文中进行身份验证时,客户端可以请求 organization
范围来映射有关用户是其成员的组织的信息。
因此,令牌将包含如下声明
"organization": {
"testcorp": {
"id": "42c3e46f-2477-44d7-a85b-d3b43f6b31fa",
"attr1": [
"value1"
]
}
}
客户端(例如,来自 ID 令牌)和资源服务器(例如,来自访问令牌)可以使用组织声明来授权访问受保护的资源,具体取决于用户是其成员的组织。
organization
范围是 realm 中内置的可选客户端范围。因此,默认情况下,此范围会添加到 realm 中创建的任何客户端。它还定义了 Organization Membership
映射器,该映射器控制组织成员资格信息如何映射到令牌。
默认情况下,组织 ID 和属性不包含在组织声明中。要包含它们,请编辑映射器并分别启用添加组织 ID 和添加组织属性选项。 |
organization
范围使用不同的格式请求
格式 | 描述 |
---|---|
|
如果用户仅属于一个组织,则映射到该组织。否则,如果用户属于多个组织,则在用户向 realm 进行身份验证时,将提示用户选择一个组织。 |
|
映射到具有给定别名的单个组织。 |
|
映射到用户所属的所有组织。 |
管理 OpenID Connect 和 SAML 客户端
客户端是可以请求用户身份验证的实体。客户端有两种形式。第一种客户端是想要参与单点登录的应用程序。这些客户端只是希望 Keycloak 为它们提供安全性。另一种客户端是请求访问令牌的客户端,以便它可以代表经过身份验证的用户调用其他服务。本节讨论配置客户端的各个方面以及执行此操作的各种方法。
管理 OpenID Connect 客户端
OpenID Connect 是推荐的用于保护应用程序的协议。它从一开始就被设计为对 Web 友好,并且最适合 HTML5/JavaScript 应用程序。
创建 OpenID Connect 客户端
要保护使用 OpenID Connect 协议的应用程序,您需要创建一个客户端。
-
单击菜单中的 Clients(客户端)。
-
点击 创建客户端。
创建客户端 -
将 客户端类型 设置为 OpenID Connect。
-
输入 客户端 ID。
此 ID 是一个字母数字字符串,用于 OIDC 请求和 Keycloak 数据库中以标识客户端。
-
为客户端提供 名称。
如果您计划本地化此名称,请设置一个替换字符串值。例如,字符串值可以是 ${myapp}。有关更多信息,请参阅《服务器开发者指南》。
-
点击 保存。
此操作将创建客户端,并将您带到 设置 选项卡,您可以在其中执行基本配置。
基本配置
设置 选项卡包含许多用于配置此客户端的选项。
常规设置
- 客户端 ID
-
用于 OIDC 请求和 Keycloak 数据库中标识客户端的字母数字 ID 字符串。
- 名称
-
Keycloak UI 界面中客户端的名称。要本地化名称,请设置一个替换字符串值。例如,字符串值可以是 ${myapp}。有关更多信息,请参阅《服务器开发者指南》。
- 描述
-
客户端的描述。此设置也可以本地化。
- 始终在控制台中显示
-
即使此用户没有活动会话,也始终在帐户控制台中列出此客户端。
访问设置
- 根 URL
-
如果 Keycloak 使用任何配置的相对 URL,则此值将添加到它们的前面。
- 主页 URL
-
当身份验证服务器需要重定向或链接回客户端时,提供默认 URL。
- 有效重定向 URI
-
必填字段。输入 URL 模式,然后单击 + 添加,单击 - 删除现有 URL,然后单击 保存。精确(区分大小写)字符串匹配用于比较有效的重定向 URI。
您可以在 URL 模式的末尾使用通配符。例如
http://host.com/path/*
。为了避免安全问题,如果传递的重定向 URI 包含 userinfo 部分,或者其路径管理对父目录 (/../
) 的访问,则不执行通配符比较,而是执行标准且安全的精确字符串匹配。完整的通配符
*
有效重定向 URI 也可以配置为允许任何 http 或 https 重定向 URI。请不要在生产环境中使用它。独占重定向 URI 模式通常更安全。有关更多信息,请参阅非特定重定向 URI。
- Web 源
-
输入 URL 模式,然后单击 + 添加,单击 - 删除现有 URL。单击 保存。
此选项处理跨域资源共享 (CORS)。如果浏览器 JavaScript 尝试向域与 JavaScript 代码来源域不同的服务器发出 AJAX HTTP 请求,则该请求必须使用 CORS。服务器必须处理 CORS 请求,否则浏览器将不会显示或允许处理该请求。此协议可防止 XSS、CSRF 和其他基于 JavaScript 的攻击。
此处列出的域 URL 嵌入在发送到客户端应用程序的访问令牌中。客户端应用程序使用此信息来决定是否允许在其上调用 CORS 请求。只有 Keycloak 客户端适配器支持此功能。有关更多信息,请参阅《保护应用程序指南》。
- 管理 URL
-
客户端的回调端点。服务器使用此 URL 进行回调,例如推送吊销策略、执行后端注销和其他管理操作。对于 Keycloak servlet 适配器,此 URL 可以是 servlet 应用程序的根 URL。有关更多信息,请参阅《保护应用程序指南》。
功能配置
- 客户端身份验证
-
OIDC 客户端的类型。
-
开启
对于执行浏览器登录并在发出访问令牌请求时需要客户端密钥的服务器端客户端。此设置应用于服务器端应用程序。
-
关闭
对于执行浏览器登录的客户端客户端。由于无法确保客户端客户端的密钥安全,因此通过配置正确的重定向 URI 来限制访问非常重要。
-
- Authorization
-
启用或禁用对此客户端的细粒度授权支持。
- 标准流程
-
如果启用,此客户端可以使用 OIDC 授权码流程。
- 直接访问授权
-
如果启用,此客户端可以使用 OIDC 直接访问授权。
- 隐式流程
-
如果启用,此客户端可以使用 OIDC 隐式流程。
- 服务帐户角色
-
如果启用,此客户端可以向 Keycloak 进行身份验证并检索专用于此客户端的访问令牌。根据 OAuth2 规范,这为此客户端启用了对
客户端凭据授权
的支持。 - 标准令牌交换
-
如果启用,此客户端可以使用标准令牌交换。
- Auth 2.0 设备授权许可
-
如果启用,此客户端可以使用 OIDC 设备授权许可。
- OIDC CIBA 许可
-
如果启用,此客户端可以使用 OIDC 客户端发起的后端通道身份验证许可。
登录设置
- 登录主题
-
用于登录、OTP、授权注册和忘记密码页面的主题。
- 需要同意
-
如果启用,用户必须同意客户端访问。
对于执行浏览器登录的客户端客户端。由于无法确保客户端客户端的密钥安全,因此通过配置正确的重定向 URI 来限制访问非常重要。
- 在屏幕上显示客户端
-
此开关在 需要同意 为 关闭 时适用。
-
关闭
同意屏幕将仅包含与配置的客户端作用域相对应的同意项。
-
开启
同意屏幕上还将有一个关于此客户端本身的条目。
-
- 客户端同意屏幕文本
-
在 需要同意 和 在屏幕上显示客户端 都启用时适用。包含同意屏幕上关于此客户端权限的文本。
注销设置
- 前端通道注销
-
如果启用 前端通道注销,则应用程序应能够按照 OpenID Connect 前端通道注销 规范通过前端通道注销用户。如果启用,您还应该提供
前端通道注销 URL
。 - 前端通道注销 URL
-
Keycloak 将使用此 URL 通过前端通道向客户端发送注销请求。如果未提供,则默认为 “主页 URL”。此选项仅在
前端通道注销
选项为 “开启” 时适用。 - 前端通道注销会话要求
-
指定在使用 前端通道注销 URL 时,注销请求中是否包含 sid(会话 ID)和 iss(颁发者)参数。
- 后端通道注销 URL
-
当向此 realm 发送注销请求(通过 end_session_endpoint)时,此 URL 将导致客户端自行注销。注销是通过发送 OIDC 后端通道注销规范中指定的注销令牌来完成的。如果省略,注销请求可能会以 Keycloak 适配器特定的格式发送到指定的
管理 URL
(如果已配置)。如果甚至管理 URL
都未配置,则不会向客户端发送注销请求。此选项仅在前端通道注销
选项为 “关闭” 时适用。 - 后端通道注销会话要求
-
指定在使用 后端通道注销 URL 时,会话 ID 声明是否包含在注销令牌中。
- 后端通道注销撤销离线会话
-
指定在使用 “后端通道注销 URL” 时,revoke_offline_access 事件是否包含在注销令牌中。当 Keycloak 收到包含此事件的注销令牌时,将撤销离线会话。
高级配置
完成 设置 选项卡上的字段后,您可以使用其他选项卡执行高级配置。例如,您可以使用 角色 或 客户端作用域 选项卡来配置为客户端定义的客户端角色或管理客户端的客户端作用域。此外,有关其他功能,请参阅本章的其余部分。
细粒度 OpenID Connect 配置
Logo URL
引用客户端应用程序 Logo 的 URL。
策略 URL
依赖方客户端向最终用户提供的 URL,用于阅读有关如何使用个人资料数据的说明。
服务条款 URL
依赖方客户端向最终用户提供的 URL,用于阅读有关依赖方服务条款的说明。
签名和加密 ID 令牌支持
Keycloak 可以根据 Json Web Encryption (JWE) 规范加密 ID 令牌。管理员确定是否为每个客户端加密 ID 令牌。
用于加密 ID 令牌的密钥是内容加密密钥 (CEK)。Keycloak 和客户端必须协商使用哪个 CEK 以及如何传递它。用于确定 CEK 的方法是密钥管理模式。“密钥加密” 是 Keycloak 支持的密钥管理模式。
在密钥加密中
-
客户端生成非对称加密密钥对。
-
公钥用于加密 CEK。
-
Keycloak 为每个 ID 令牌生成一个 CEK
-
Keycloak 使用生成的 CEK 加密 ID 令牌
-
Keycloak 使用客户端的公钥加密 CEK。
-
客户端使用其私钥解密加密的 CEK
-
客户端使用解密的 CEK 解密 ID 令牌。
除了客户端之外,任何一方都无法解密 ID 令牌。
客户端必须将其用于加密 CEK 的公钥传递给 Keycloak。Keycloak 支持从客户端提供的 URL 下载公钥。客户端必须根据 Json Web Keys (JWK) 规范提供公钥。
步骤如下
-
打开客户端的 密钥 选项卡。
-
将 JWKS URL 切换为 “开启”。
-
在 JWKS URL 文本框中输入客户端的公钥 URL。
密钥加密的算法在 Json Web Algorithm (JWA) 规范中定义。Keycloak 支持
-
RSAES-PKCS1-v1_5(RSA1_5)
-
使用默认参数的 RSAES OAEP (RSA-OAEP)
-
使用 SHA-256 和 MFG1 的 RSAES OAEP 256 (RSA-OAEP-256)
选择算法的步骤如下
-
打开客户端的 高级 选项卡。
-
打开 细粒度 OpenID Connect 配置。
-
从 ID 令牌加密内容加密算法 下拉菜单中选择算法。
OpenID Connect 兼容模式
本节是为了向后兼容而存在的。单击问号图标以获取每个字段的详细信息。
启用 OAuth 2.0 相互 TLS 证书绑定访问令牌
相互 TLS 将访问令牌和刷新令牌与客户端证书绑定在一起,该证书在 TLS 握手期间交换。这种绑定可以防止攻击者使用被盗的令牌。
这种类型的令牌是持有者密钥令牌。与持有者令牌不同,持有者密钥令牌的接收者可以验证令牌的发送者是否合法。
如果此设置开启,则工作流程如下
-
令牌请求在授权码流程或混合流程中发送到令牌端点。
-
Keycloak 请求客户端证书。
-
Keycloak 接收客户端证书。
-
Keycloak 成功验证客户端证书。
如果验证失败,Keycloak 将拒绝令牌。
在以下情况下,Keycloak 将验证发送访问令牌或刷新令牌的客户端
-
令牌刷新请求与持有者密钥刷新令牌一起发送到令牌端点。
-
UserInfo 请求与持有者密钥访问令牌一起发送到 UserInfo 端点。
-
注销请求与持有者密钥刷新令牌一起发送到不符合 OIDC 标准的 Keycloak 专有注销端点。
有关更多详细信息,请参阅 OAuth 2.0 相互 TLS 客户端身份验证和证书绑定访问令牌中的相互 TLS 客户端证书绑定访问令牌。
Keycloak 客户端适配器不支持持有者密钥令牌验证。Keycloak 适配器将访问令牌和刷新令牌视为持有者令牌。 |
OAuth 2.0 在应用层证明所有权 (DPoP)
DPoP 将访问令牌和刷新令牌与客户端密钥对的公钥部分绑定在一起。这种绑定可以防止攻击者使用被盗的令牌。
这种类型的令牌是持有者密钥令牌。与持有者令牌不同,持有者密钥令牌的接收者可以验证令牌的发送者是否合法。
如果客户端开关 在令牌请求中需要证明所有权 (DPoP) 标头
开启,则工作流程如下
-
令牌请求在授权码流程或混合流程中发送到令牌端点。
-
Keycloak 请求 DPoP 证明。
-
Keycloak 接收 DPoP 证明。
-
Keycloak 成功验证 DPoP 证明。
如果验证失败,Keycloak 将拒绝令牌。
如果开关 在令牌请求中需要证明所有权 (DPoP) 标头
关闭,客户端仍然可以在令牌请求中发送 DPoP
证明。在这种情况下,Keycloak 将验证 DPoP 证明并将指纹添加到令牌。但是,如果开关关闭,则 Keycloak 服务器不会为此客户端强制执行 DPoP 绑定。如果您想确保特定客户端始终使用 DPoP 绑定,建议开启此开关。
在以下情况下,Keycloak 将验证发送访问令牌或刷新令牌的客户端
-
令牌刷新请求与持有者密钥刷新令牌一起发送到令牌端点。此验证仅针对 DPoP 规范中描述的公共客户端完成。对于机密客户端,由于已通过适当的客户端凭据进行客户端身份验证以确保请求来自合法客户端,因此不进行验证。对于公共客户端,访问令牌和刷新令牌都绑定了 DPoP。对于机密客户端,只有访问令牌绑定了 DPoP。
-
UserInfo 请求与持有者密钥访问令牌一起发送到 UserInfo 端点。
-
注销请求与持有者密钥刷新令牌一起发送到不符合 OIDC 标准的 Keycloak 专有注销端点。此验证仅针对上述公共客户端完成。
有关更多详细信息,请参阅 OAuth 2.0 证明所有权 (DPoP)。
Keycloak 客户端适配器不支持 DPoP 持有者密钥令牌验证。Keycloak 适配器将访问令牌和刷新令牌视为持有者令牌。 |
DPoP 是预览功能,尚未完全支持。此功能默认禁用。 要启用,请使用 |
OIDC 的高级设置
OpenID Connect 的高级设置允许您在客户端级别为会话和令牌超时配置覆盖。
配置 | 描述 |
---|---|
访问令牌生命周期 |
该值会覆盖同名的 realm 选项。 |
客户端会话空闲 |
该值会覆盖同名的 realm 选项。该值应短于全局的 SSO 会话空闲。 |
客户端会话最大值 |
该值会覆盖同名的 realm 选项。该值应短于全局的 SSO 会话最大。 |
客户端离线会话空闲 |
此设置允许您为客户端配置更短的离线会话空闲超时。超时是指会话保持空闲的时间量,超过此时间后,Keycloak 将撤销其离线令牌。如果未设置,则使用 realm 的 离线会话空闲。 |
客户端离线会话最大 |
此设置允许您为客户端配置更短的离线会话最大生命周期。生命周期是指 Keycloak 撤销相应离线令牌之前的最长时间。此选项需要全局在 realm 中启用离线会话最大受限,并且默认为离线会话最大。 |
代码交换的代码质询方法证明密钥
如果攻击者窃取了合法客户端的授权码,代码交换的密钥证明 (PKCE) 可防止攻击者接收应用于该代码的令牌。
管理员可以选择以下选项之一
- (空白)
-
除非客户端向 Keycloak 授权端点发送适当的 PKCE 参数,否则 Keycloak 不会应用 PKCE。
- S256
-
Keycloak 应用于代码质询方法为 S256 的客户端 PKCE。
- plain
-
Keycloak 应用于代码质询方法为 plain 的客户端 PKCE。
有关更多详细信息,请参阅 RFC 7636 OAuth 公共客户端的代码交换的密钥证明。
ACR 到身份验证级别 (LoA) 映射
在客户端的高级设置中,您可以定义哪个 身份验证上下文类引用 (ACR)
值映射到哪个 身份验证级别 (LoA)
。此映射也可以在 realm 中指定,如ACR 到 LoA 映射中所述。最佳实践是在 realm 级别配置此映射,这允许跨多个客户端共享相同的设置。
当从该客户端向 Keycloak 发送登录请求时,如果没有 acr_values
参数,也没有附加 acr
声明的 claims
参数,则可以使用 默认 ACR 值
来指定默认值。请参阅 官方 OIDC 动态客户端注册规范。
请注意,默认 ACR 值用作默认级别,但是,它不能可靠地用于强制使用特定级别登录。例如,假设您将 默认 ACR 值 配置为级别 2。然后,默认情况下,将要求用户使用级别 2 进行身份验证。但是,当用户显式地将参数附加到登录请求中,例如 acr_values=1 时,将使用级别 1。因此,如果客户端确实需要级别 2,则建议客户端检查 ID 令牌中是否存在 acr 声明,并仔细检查它是否包含请求的级别 2。要在 Keycloak 端实际强制使用某个 ACR,请使用 最小 ACR 值 设置。这允许管理员即使在无法验证令牌中请求的 acr 声明的应用程序上,也能强制执行 ACR。 |
有关更多详细信息,请参阅 逐步验证 和 官方 OIDC 规范。
机密客户端凭据
如果客户端的客户端身份验证设置为 开启,则必须在 凭据 选项卡下配置客户端的凭据。
客户端身份验证器下拉列表指定要用于客户端的凭据类型。
客户端 ID 和密钥
此选项是默认设置。密钥会自动生成。如有必要,单击 重新生成 以重新创建密钥。
签名 JWT 是“签名 JSON Web 令牌”。
在此身份验证器中,您可以强制执行客户端使用的 签名算法(默认情况下任何算法都有效)以及 JWT 令牌允许的 最大过期时间(在此期间之后收到的令牌将不被接受,因为它们太旧了,请注意令牌应在身份验证之前立即颁发,默认为 60 秒)。
选择此凭据类型时,您还必须在 密钥
选项卡中为客户端生成私钥和证书。私钥将用于签署 JWT,而证书将由服务器用于验证签名。
单击 生成新密钥
按钮开始此过程。
-
选择要使用的存档格式。
-
输入 密钥密码。
-
输入 存储密码。
-
单击 生成。
当您生成密钥时,Keycloak 将存储证书,您可以下载客户端的私钥和证书。
您还可以使用外部工具生成密钥,然后通过单击 导入证书 来导入客户端的证书。
-
选择证书的存档格式。
-
输入存储密码。
-
单击 导入文件 选择证书文件。
-
单击 导入。
如果您单击 使用 JWKS URL,则无需导入证书。在这种情况下,您可以提供在 JWK 格式中发布公钥的 URL。使用此选项,如果密钥发生更改,Keycloak 会重新导入密钥。
如果您正在使用由 Keycloak 适配器保护的客户端,您可以使用此格式配置 JWKS URL,假设 https://myhost.com/myapp 是您的客户端应用程序的根 URL
https://myhost.com/myapp/k_jwks
有关更多详细信息,请参阅 服务器开发人员指南。
使用客户端密钥签名的 JWT
如果选择此选项,您可以使用客户端密钥而不是私钥签名的 JWT。
客户端密钥将由客户端用于签署 JWT。
与 签名 JWT 身份验证器一样,您可以配置 签名算法 和 JWT 令牌的 最大过期时间。
X509 证书
Keycloak 将验证客户端在 TLS 握手期间是否使用了正确的 X509 证书。
验证器还会使用配置的正则表达式验证表达式检查证书的 Subject DN 字段。对于某些用例,接受所有证书就足够了。在这种情况下,您可以使用 (.*?)(?:$)
表达式。
Keycloak 有两种方法可以从请求中获取客户端 ID
-
查询中的
client_id
参数(在 OAuth 2.0 规范的第 2.2 节中描述)。 -
以表单参数形式提供
client_id
。
客户端密钥轮换
请注意,客户端密钥轮换支持正在开发中。实验性地使用此功能。 |
客户端密钥轮换策略提供更高的安全性,以减轻诸如密钥泄露等问题。启用后,Keycloak 最多支持每个客户端同时拥有两个活动密钥。该策略根据以下设置管理轮换
-
密钥过期时间: [秒] - 轮换密钥时,这是新密钥的过期时间。添加到密钥创建日期的时长,以秒为单位。在策略执行时计算。
-
已轮换密钥过期时间: [秒] - 轮换密钥时,此值是旧密钥的剩余过期时间。此值应始终小于密钥过期时间。当值为 0 时,旧密钥将在客户端轮换期间立即删除。添加到密钥轮换日期的时长,以秒为单位。在策略执行时计算。
-
更新期间轮换的剩余过期时间: [秒] - 动态客户端更新应执行客户端密钥轮换的时间段。在策略执行时计算。
当发生客户端密钥轮换时,将生成一个新的主密钥,旧的客户端主密钥将变为辅助密钥,并具有新的过期日期。
客户端密钥轮换规则
轮换不会自动发生或通过后台进程发生。为了执行轮换,需要在客户端上执行更新操作,可以通过 Keycloak 管理控制台通过客户端凭据选项卡中的 重新生成密钥 功能或 Admin REST API 来完成。当调用客户端更新操作时,会根据以下规则发生密钥轮换
-
当 密钥过期时间 的值小于当前日期时。
-
在动态客户端注册客户端更新请求期间,如果 更新期间轮换的剩余过期时间 的值与当前日期和 密钥过期时间 之间的时间段匹配,则客户端密钥将自动轮换。
此外,可以通过 Admin REST API 随时强制执行客户端密钥轮换。
在创建新客户端期间,如果客户端密钥轮换策略处于活动状态,则将自动应用该行为。 |
要将密钥轮换行为应用于现有客户端,请在定义策略后更新该客户端,以便应用该行为。 |
创建 OIDC 客户端密钥轮换策略
以下是定义密钥轮换策略的示例
-
在菜单中单击“Realm 设置”。
-
单击 客户端策略 选项卡。
-
在 配置文件 页面上,单击 创建客户端配置文件。
创建配置文件 -
在 名称 中输入任何名称。
-
在 描述 中输入描述,以帮助您识别配置文件的用途。
-
点击 保存。
此操作将创建配置文件,并允许您配置执行器。
-
单击 添加执行器 以为此配置文件配置执行器。
创建配置文件执行器 -
为 执行器类型 选择 secret-rotation。
-
为 密钥过期时间 输入每个密钥的最大持续时间,以秒为单位。
-
为 已轮换密钥过期时间 输入每个已轮换密钥的最大持续时间,以秒为单位。
请记住,已轮换密钥过期时间 值必须始终小于 密钥过期时间。 -
为 剩余过期时间 输入时间量(以秒为单位),在此时间之后,任何更新操作都将更新客户端。
-
点击 添加。
在上面的示例中
-
每个密钥有效期为一周。
-
轮换后的密钥在两天后过期。
-
动态客户端的更新窗口在密钥过期前一天开始。
-
-
返回到 客户端策略 选项卡。
-
单击 策略。
-
单击 创建客户端策略。
创建客户端密钥轮换策略 -
在 名称 中输入任何名称。
-
在描述中输入描述,以帮助您识别策略的用途。
-
点击 保存。
此操作将创建策略,并使您可以将策略与配置文件关联。它还允许您配置策略执行的条件。
-
在“条件”下,单击添加条件。
创建客户端密钥轮换策略条件 -
要将行为应用于所有机密客户端,请在“条件类型”字段中选择client-access-type。
要应用于特定客户端组,另一种方法是在“条件类型”字段中选择client-roles类型。 这样,您可以创建特定的角色,并为每个角色分配自定义轮换配置。
-
在“客户端访问类型”字段中添加confidential。
-
点击 添加。
-
返回策略设置中的“客户端配置文件”下,单击添加客户端配置文件,然后从列表中选择“每周客户端密钥轮换配置文件”,然后单击添加。
客户端密钥轮换策略
要将密钥轮换行为应用于现有客户端,请按照以下步骤操作 使用管理控制台
|
-
通过客户端上的更新操作
-
通过重新生成客户端密钥端点
使用服务帐户
每个 OIDC 客户端都有一个内置的服务帐户。 使用此服务帐户获取访问令牌。
来自访问令牌的角色是以下项的交集:
-
客户端的角色范围映射与从链接的客户端范围继承的角色范围映射相结合。
-
服务帐户角色。
要调用的 REST URL 是 /realms/{realm-name}/protocol/openid-connect/token
。 此 URL 必须作为 POST 请求调用,并且要求您在请求中发布客户端凭据。
默认情况下,客户端凭据由客户端的 clientId 和 clientSecret 在 Authorization: Basic 标头中表示,但您也可以使用签名的 JWT 断言或任何其他自定义客户端身份验证机制对客户端进行身份验证。
您还需要按照 OAuth2 规范将 grant_type 参数设置为“client_credentials”。
例如,检索服务帐户的 POST 调用可能如下所示
POST /realms/demo/protocol/openid-connect/token
Authorization: Basic cHJvZHVjdC1zYS1jbGllbnQ6cGFzc3dvcmQ=
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
响应将类似于 OAuth 2.0 规范中的此访问令牌响应。
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer",
"expires_in":60
}
默认情况下,仅返回访问令牌。 默认情况下,不返回刷新令牌,并且在 Keycloak 端不会创建用户会话。 由于缺少刷新令牌,因此在访问令牌过期时需要重新身份验证。 但是,这种情况并不意味着 Keycloak 服务器有任何额外的开销,因为默认情况下不会创建会话。
在这种情况下,注销是不必要的。 但是,可以通过向 OAuth2 撤销端点发送请求来撤销已颁发的访问令牌,如OpenID Connect 端点部分所述。
有关更多详细信息,请参阅客户端凭据授权。
令牌中的角色映射
添加到令牌的角色是以下项的交集:
分配给用户的角色
分配给用户的角色可以在角色映射中定义,如此节中所述。 少量细节:
角色协议映射器
与其他声明类似,角色通过专用的协议映射器添加到为客户端颁发的访问令牌中。 领域中定义了一个内置客户端范围角色。 由于它是领域默认客户端范围,因此默认情况下将其定义为每个领域客户端的默认客户端范围。 您可以通过查看“客户端范围”选项卡,然后查找角色客户端范围,在管理控制台中看到此客户端范围。 此客户端范围默认包含以下协议映射器:
-
协议映射器领域角色 - 此协议映射器用于将领域角色添加到令牌声明中。 默认情况下,配置如下所示:
-
协议映射器客户端角色 - 此协议映射器用于将客户端角色添加到令牌声明中。 默认情况下,配置如下所示:
-
协议映射器受众解析 - 此协议映射器用于根据应用的客户端角色填充访问令牌中的
aud
声明。 有关此映射器的详细信息,请参见受众解析部分。
正如您在领域角色和客户端角色映射器的配置中看到的那样,可以配置:
-
角色是仅添加到访问令牌,还是也添加到其他令牌,例如 ID 令牌。 默认情况下,角色添加到访问令牌和内省端点。
-
角色将添加到哪些声明中。 默认情况下,领域角色添加到
realm_access
声明中。 因此,例如,包含 2 个领域角色role1
和role2
的 JWT 令牌中的声明将类似于这样:"realm_access": { "roles": [ "role1", "role2" ] }
默认情况下,客户端角色添加到
resource_access
令牌声明中。 此声明在令牌中将如下所示,其中包含客户端account
的客户端角色manage-account
和manage-account-links
以及客户端target-client1
的客户端角色target-client1-role
:"resource_access": { "target-client1": { "roles": [ "target-client1-role" ] }, "account": { "roles": [ "manage-account", "manage-account-links" ] } }
通过调整角色协议映射器的“令牌声明名称”配置选项,可以指定将这些角色添加到令牌中的配置声明中。
如果您只想为一个特定客户端更新角色声明(例如,客户端 foo
希望领域角色在声明 my-realm-roles
中而不是声明 realm_access
中),则可以从您的客户端中删除默认客户端范围角色,而是在您的客户端的专用客户端范围中配置领域/客户端协议映射器。
受众支持
通常,Keycloak 的部署环境由一组机密或公共客户端应用程序组成,这些应用程序使用 Keycloak 进行身份验证。 这些客户端是前端客户端,可以直接将用户重定向到 Keycloak 以请求浏览器身份验证。 然后,特定客户端将在成功身份验证后收到一组令牌。
服务(OAuth 2 规范中的资源服务器)也可用,它们为来自客户端应用程序的请求提供服务,并向这些应用程序提供资源。 这些服务需要从前端应用程序或其他服务发送给它们的访问令牌(Bearer 令牌)来验证请求的身份。
必须注意确保访问令牌具有有限的权限,并且特定访问令牌不会被服务滥用以访问其他第三方服务。 在服务之间信任度较低的环境中,您可能会遇到以下示例场景:
-
前端客户端应用程序
frontend-client
需要针对 Keycloak 进行身份验证。 -
Keycloak 验证用户身份。
-
Keycloak 向应用程序
frontend-client
颁发令牌。 -
frontend-client
应用程序使用令牌来调用服务service1
。 -
service1
服务将响应返回给应用程序。 但假设此服务将尝试滥用令牌并将其保留以供进一步使用。 -
然后,
service1
使用先前发送给它的应用程序令牌调用另一个服务service2
。service2
不检查令牌是否不应该用于调用它,它将为请求提供服务并返回成功响应。 这会导致安全性被破坏,因为service1
滥用令牌以代表客户端应用程序frontend-client
访问其他服务。
这种情况在服务之间具有高度信任的环境中不太可能发生,但在信任度较低的环境中则不然。
为了防止对访问令牌的任何滥用,访问令牌可以包含声明 aud
,该声明表示受众。 声明 aud
通常应表示令牌应该使用的所有服务的客户端 ID。 在服务之间信任度较低的环境中,建议:
-
限制令牌上的受众,以确保访问令牌仅包含有限数量的受众。
-
配置您的服务以验证令牌上的受众。
为了防止上面示例中的 service1
滥用令牌,安全流程的变体可能如下所示:
-
前端应用程序
frontend-client
针对 Keycloak 进行身份验证。 -
Keycloak 验证用户身份。
-
Keycloak 向
frontend-client
应用程序颁发令牌。frontend-client
知道它将需要调用service1
,因此它在发送到 Keycloak 的身份验证请求中放置scope=service1-scope
。 范围service1-scope
是一个客户端范围,可能需要由管理员创建。 在以下部分中,有一些关于如何设置此类客户端范围的选项。 令牌声明将如下所示:"aud": "service1"
这声明客户端可以使用此访问令牌来调用
service1
。 -
frontend-client
应用程序使用令牌来调用服务service1
。 -
service1
为客户端应用程序frontend-application
的请求提供服务。 但假设此服务将尝试滥用令牌并将其保留以供进一步使用。 -
然后,
service1
将尝试使用令牌调用service2
。 调用不成功,因为service2
服务检查令牌上的受众,并发现其受众仅针对service1
。 因此,service2
将拒绝该请求,并将错误返回给service1
。 此行为是预期的,并且安全性不会被破坏。
服务调用另一个服务的能力
在某些环境中,可能需要 service1
从 service2
检索其他数据,以将数据返回给原始客户端应用程序 frontend-client
。 为了使此功能正常工作,有几种可能性:
-
确保颁发给
frontend-client
的初始访问令牌将同时包含service1
和service2
作为受众。 假设设置了正确的客户端范围,frontend-client
可以使用scope=service1-scope service2-scope
作为scope
参数的值。 然后,颁发的令牌将包含aud
声明,如下所示:"aud": [ "service1", "service2" ]
这样的访问令牌可以用于调用
service1
或service2
。 因此,service1
将能够成功使用此类令牌来调用service2
以检索其他数据。 -
之前的在令牌受众中同时包含两个服务的方法允许
service1
调用service2
。然而,这也意味着frontend-client
也可以直接使用其访问令牌来调用service2
。这在某些情况下可能是不希望发生的。您可能希望service1
能够调用service2
,但同时,您不希望frontend-client
能够直接调用service2
。针对这种情况的解决方案可能是使用 令牌交换。在这种情况下,初始令牌仍然只将service1
作为受众。但是,一旦令牌被发送到service1
,service1
可以发送令牌交换请求来交换另一个令牌,该令牌将把service2
作为受众。有关如何使用令牌交换的详细信息,请参阅 令牌交换文档。
基于客户端角色自动添加受众
在默认客户端作用域roles中定义了一个受众解析协议映射器。该映射器检查是否有客户端至少有一个可用于当前令牌的客户端角色。然后,每个此类客户端的客户端 ID 将被添加为受众,如果您的服务客户端依赖于客户端角色,这将非常有用。服务客户端通常可以是没有任何启用流程的客户端,它可能没有直接向自身颁发任何令牌。它代表 OAuth 2 资源服务器。
令牌角色映射部分包含有关如何将客户端角色添加到令牌的详细信息。另请参阅下面的示例。
示例 - 令牌角色映射和受众声明
以下是如何使用客户端角色使 aud
声明添加到令牌的示例步骤
-
创建一个 OIDC 客户端
service1
。可以禁用此客户端的标准流程或任何其他流程,因为它是一个服务客户端,可能永远不会自行直接进行身份验证。如果需要,标准令牌交换开关可能是例外情况,如上所述。 -
转到该客户端的角色选项卡,并创建客户端角色
service1-role
。 -
在同一域中创建用户
john
,并将客户端service1
的客户端角色service1-role
分配给他。 此部分包含有关如何执行此操作的一些详细信息。 -
创建名为
service1-scope
的客户端作用域。可以将其标记为包含在令牌作用域中为开启。有关如何创建和设置新客户端作用域的详细信息,请参阅 此部分。 -
转到
service1-scope
的作用域选项卡,并将客户端service1
的角色service1-role
添加到此客户端作用域的 角色作用域映射 中 -
在域中创建另一个客户端
frontend-client
。 -
单击此客户端的客户端作用域选项卡,选择第一个专用客户端作用域
frontend-client-dedicated
,然后转到作用域选项卡并禁用允许全部作用域开关 -
返回此客户端的客户端作用域选项卡,然后单击添加客户端作用域,并将
service1-scope
链接为可选。有关更多详细信息,请参阅 客户端作用域链接部分。 -
单击 客户端作用域 中的子选项卡评估,如 此部分 中所述。当填写用户
john
和子选项卡 生成的访问令牌时,可以看到没有任何aud
声明,因为在生成的示例令牌中没有任何客户端角色。但是,当也将作用域service1-scope
添加到作用域字段时,可以看到客户端角色service1-role
,因为它在service1-scope
的角色作用域映射中,并且也在用户john
的角色映射中。因此,aud
声明也将包含service1
。
如果您希望始终将 service1
受众应用于颁发给 frontend-client
客户端的令牌(不使用参数 scope=service1-scope
),那么可以执行以下任一操作
-
将
service1-scope
分配为默认客户端作用域,而不是可选客户端作用域 -
将
service1-role
的角色作用域映射直接添加到客户端的 专用客户端作用域。在这种情况下,您将完全不需要service1-scope
。
请注意,由于此方法基于客户端角色,因此它还需要用户本身(以上示例中的用户 john
)是客户端 service1
的某些客户端角色的成员。否则,如果没有分配任何客户端角色,则不会包含受众 service1
。如果您希望无论客户端角色如何都包含受众,请参阅 硬编码受众 部分。
前端客户端本身不会自动添加到访问令牌受众中,因此可以轻松区分访问令牌和 ID 令牌,因为访问令牌不会包含为其颁发令牌的客户端作为受众。 如果您需要将客户端本身作为受众,请参阅 硬编码受众 选项。但是,不建议将同一客户端同时用作前端和 REST 服务。 |
硬编码受众
当您的服务依赖于域角色或根本不依赖于令牌中的角色时,使用硬编码受众可能很有用。硬编码受众是一个协议映射器,它会将指定服务客户端的客户端 ID 作为受众添加到令牌中。如果您想使用与客户端 ID 不同的受众,可以使用任何自定义值,例如 URL。
您可以直接将协议映射器添加到前端客户端。如果直接添加协议映射器,则始终会添加受众。
为了更好地控制协议映射器,您可以在专用客户端作用域上创建协议映射器,例如,可以将其命名为 service2。
以下是硬编码受众的示例步骤
-
创建一个客户端
service2
-
创建一个客户端作用域
service2-scope
。 -
在该客户端作用域的映射器选项卡中,选择配置新映射器,然后选择受众
-
选择包含的客户端受众为
service2
,然后保存映射器受众协议映射器 -
将新创建的客户端作用域与某些客户端链接。例如,它可以作为可选客户端作用域链接到 上一个示例 中创建的客户端
frontend-client
。 -
您可以选择为链接了客户端作用域的客户端(例如
frontend-client
)评估客户端作用域并生成示例访问令牌。如果service2-scope
包含在 scope 参数中(当您将其分配为可选客户端作用域时),则受众service2
将添加到生成的访问令牌的受众中。
在您的机密客户端应用程序中,确保使用了 scope 参数。当您要颁发用于访问 service2
的令牌时,必须包含类似 scope=service2-scope 的值。
如果您的应用程序使用 javascript 适配器,请参阅 Keycloak JavaScript 适配器 部分,了解如何发送带有期望值的 scope 参数。
如果您希望在请求中不包含 scope
参数,则可以将 service2-scope
链接为默认客户端作用域,或者使用您在其中配置此映射器的客户端专用作用域。如果您希望始终为 OIDC 客户端 frontend-client
的所有身份验证请求应用受众,这将非常有用。
默认情况下,受众和受众解析协议映射器仅将受众添加到访问令牌。ID 令牌通常仅包含单个受众,即为其颁发令牌的客户端 ID,这是 OpenID Connect 规范的要求。但是,访问令牌不一定具有为其颁发令牌的客户端 ID,除非 受众 映射器添加了它。 |
创建 SAML 客户端
Keycloak 支持 SAML 2.0 用于注册的应用程序。支持 POST 和重定向绑定。您可以选择要求客户端签名验证。您也可以让服务器对响应进行签名和/或加密。
-
单击菜单中的 Clients(客户端)。
-
单击创建客户端以转到创建客户端页面。
-
将客户端类型设置为 SAML。
创建客户端 -
输入客户端的 客户端 ID。这通常是一个 URL,并且是应用程序发送的 SAML 请求中期望的 issuer 值。
-
单击保存。此操作将创建客户端并将您带到设置选项卡。
以下部分描述了此选项卡上的每个设置。
设置选项卡
设置 选项卡包含许多用于配置此客户端的选项。
常规设置
- 客户端 ID
-
字母数字 ID 字符串,用于 OIDC 请求和 Keycloak 数据库中以标识客户端。此值必须与 AuthNRequests 发送的 issuer 值匹配。Keycloak 从 Authn SAML 请求中提取 issuer,并通过此值将其与客户端匹配。
- 名称
-
Keycloak UI 屏幕中客户端的名称。要本地化名称,请设置替换字符串值。例如,字符串值如 ${myapp}。有关更多信息,请参阅 服务器开发者指南。
- 描述
-
客户端的描述。此设置也可以本地化。
- 始终在控制台中显示
-
即使此用户没有活动会话,也始终在帐户控制台中列出此客户端。
访问设置
- 根 URL
-
当 Keycloak 使用配置的相对 URL 时,此值将前置到 URL。
- 主页 URL
-
如果 Keycloak 需要链接到客户端,则使用此 URL。
- 有效重定向 URI
-
输入 URL 模式,然后单击 + 号添加。单击 - 号删除。单击保存以保存这些更改。通配符值仅允许在 URL 的末尾。例如,http://host.com/*$$。当未注册确切的 SAML 端点且 Keycloak 从请求中提取断言消费者 URL 时,将使用此字段。
- IDP 发起的 SSO URL 名称
-
当您要执行 IDP 发起的 SSO 时,引用客户端的 URL 片段名称。将此项留空将禁用 IDP 发起的 SSO。您将从浏览器引用的 URL 将是:server-root/realms/{realm-name}/protocol/saml/clients/{client-url-name}
- IDP 发起的 SSO 中继状态
-
当您要执行 IDP 发起的 SSO 时,您希望与 SAML 请求一起发送的中继状态。
- 主 SAML 处理 URL
-
此 URL 用于所有 SAML 请求,并且响应将定向到 SP。它用作断言消费者服务 URL 和单点注销服务 URL。
如果登录请求包含断言消费者服务 URL,则这些登录请求将优先。此 URL 必须通过注册的有效重定向 URI 模式进行验证。
SAML 能力
- 名称 ID 格式
-
主题的名称 ID 格式。如果在请求中未指定名称 ID 策略,或者将强制名称 ID 格式属性设置为“开启”,则使用此格式。
- 强制名称 ID 格式
-
如果请求具有名称 ID 策略,则忽略它,并使用在管理控制台中名称 ID 格式下配置的值。
- 强制 POST 绑定
-
默认情况下,Keycloak 使用原始请求的初始 SAML 绑定进行响应。通过启用强制 POST 绑定,即使原始请求使用了重定向绑定,Keycloak 也使用 SAML POST 绑定进行响应。
- 强制 artifact 绑定
-
如果启用,响应消息将通过 SAML ARTIFACT 绑定系统返回到客户端。
- 包含 AuthnStatement
-
SAML 登录响应可以指定使用的身份验证方法,例如密码,以及登录和会话过期的的时间戳。Include AuthnStatement 默认启用,以便 AuthnStatement 元素将包含在登录响应中。将其设置为 OFF 会阻止客户端确定最大会话时长,这可能会创建永不过期的客户端会话。
- 包含 OneTimeUse 条件
-
如果启用,则 OneTimeUse 条件将包含在登录响应中。
- 优化 REDIRECT 签名密钥查找
-
当设置为 ON 时,SAML 协议消息将包含 Keycloak 原生扩展。此扩展包含签名密钥 ID 的提示。SP 使用此扩展进行签名验证,而不是尝试使用密钥验证签名。
此选项适用于 REDIRECT 绑定,其中签名在查询参数中传输,并且在签名信息中找不到此信息。这与 POST 绑定消息相反,在 POST 绑定消息中,密钥 ID 始终包含在文档签名中。
当 Keycloak 服务器和适配器提供 IDP 和 SP 时,将使用此选项。此选项仅在 Sign Documents 设置为 ON 时相关。
签名和加密
- 签署文档
-
当设置为 ON 时,Keycloak 使用 realm 的私钥签署文档。
- 签署断言
-
断言已签名并嵌入在 SAML XML Auth 响应中。
- 签名算法
-
用于签署 SAML 文档的算法。请注意,基于
SHA1
的算法已被弃用,并可能在未来的版本中删除。我们建议使用比*_SHA1
更安全的算法。此外,对于*_SHA1
算法,如果 SAML 客户端在 Java 17 或更高版本上运行,则验证签名将不起作用。 - SAML 签名密钥名称
-
使用 POST 绑定发送的已签名 SAML 文档在 KeyName 元素中包含签名密钥的标识。此操作可以通过 SAML Signature Key Name 选项控制。此选项控制 Keyname 的内容。
-
KEY_ID KeyName 包含密钥 ID。此选项为默认选项。
-
CERT_SUBJECT KeyName 包含来自与 realm 密钥对应的证书的主题。Microsoft Active Directory Federation Services 期望使用此选项。
-
NONE KeyName 提示将完全从 SAML 消息中省略。
-
- 规范化方法
-
XML 签名的规范化方法。
密钥选项卡
- 加密断言
-
使用 realm 的私钥加密 SAML 文档中的断言。AES 算法使用 128 位密钥大小。
- 客户端签名必需
-
如果启用 Client Signature Required,则来自客户端的文档应进行签名。Keycloak 将使用在“密钥”选项卡中设置的客户端公钥或证书来验证此签名。
- 允许 ECP 流
-
如果为 true,则允许此应用程序使用 SAML ECP 配置文件进行身份验证。
高级选项卡
此选项卡有许多用于特定情况的字段。某些字段在其他主题中介绍。有关其他字段的详细信息,请单击问号图标。
精细粒度 SAML 端点配置
- Logo URL
-
引用客户端应用程序 Logo 的 URL。
- 策略 URL
-
依赖方客户端向最终用户提供的 URL,用于阅读有关如何使用个人资料数据的说明。
- 服务条款 URL
-
依赖方客户端向最终用户提供的 URL,用于阅读有关依赖方服务条款的说明。
- Assertion Consumer Service POST 绑定 URL
-
Assertion Consumer Service 的 POST 绑定 URL。
- Assertion Consumer Service Redirect 绑定 URL
-
Assertion Consumer Service 的 Redirect 绑定 URL。
- Logout Service POST 绑定 URL
-
Logout Service 的 POST 绑定 URL。
- Logout Service Redirect 绑定 URL
-
Logout Service 的 Redirect 绑定 URL。
- Logout Service Artifact 绑定 URL
-
Logout Service 的 Artifact 绑定 URL。当与“强制 Artifact 绑定”选项一起设置时,登录和注销流程都将强制使用 Artifact 绑定。除非设置此属性,否则注销不会使用 Artifact 绑定。
- Logout Service SOAP 绑定 URL
-
Logout Service 的 Redirect 绑定 URL。仅在使用 back channel logout 时适用。
- Artifact 绑定 URL
-
用于发送 HTTP artifact 消息的 URL。
- Artifact Resolution Service
-
客户端 SOAP 端点的 URL,用于向其发送
ArtifactResolve
消息。
IDP 发起的登录
IDP 发起的登录是一项功能,允许您在 Keycloak 服务器上设置一个端点,该端点将使您登录到特定的应用程序/客户端。在客户端的设置选项卡中,您需要指定IDP Initiated SSO URL Name。这是一个简单的字符串,其中不包含空格。之后,您可以使用以下 URL 引用您的客户端:root/realms/{realm-name}/protocol/saml/clients/{url-name}
IDP 发起的登录实现优先选择 POST 绑定而不是 REDIRECT 绑定(有关更多信息,请查看 saml 绑定)。因此,最终的绑定和 SP URL 按以下方式选择
-
如果定义了特定的 Assertion Consumer Service POST Binding URL(在客户端设置的**精细粒度 SAML 端点配置**部分内),则通过该 URL 使用 POST 绑定。
-
如果指定了通用的 Master SAML Processing URL,则再次在此通用 URL 中使用 POST 绑定。
-
作为最后的手段,如果配置了 Assertion Consumer Service Redirect Binding URL(在**精细粒度 SAML 端点配置**内),则使用 REDIRECT 绑定和此 URL。
如果您的客户端需要特殊的 relay state,您也可以在**设置**选项卡中的 IDP Initiated SSO Relay State 字段中配置它。或者,浏览器可以在 RelayState 查询参数中指定 relay state,例如 root/realms/{realm-name}/protocol/saml/clients/{url-name}?RelayState=thestate
。
当使用 身份代理 时,可以为来自外部 IDP 的客户端设置 IDP 发起的登录。实际客户端在代理 IDP 中设置为 IDP 发起的登录,如上所述。外部 IDP 必须为应用程序 IDP 发起的登录设置客户端,该登录将指向一个特殊的 URL,该 URL 指向代理并表示代理 IDP 中所选客户端的 IDP 发起的登录端点。这意味着在外部 IDP 的客户端设置中
-
IDP Initiated SSO URL Name 设置为将作为 IDP 发起的登录初始点发布的名称,
-
Assertion Consumer Service POST Binding URL 在**精细粒度 SAML 端点配置**部分中必须设置为以下 URL:
broker-root/realms/{broker-realm}/broker/{idp-name}/endpoint/clients/{client-id}
,其中-
broker-root 是基础代理 URL
-
broker-realm 是声明外部 IDP 的代理中的 realm 名称
-
idp-name 是代理中外部 IDP 的名称
-
client-id 是在代理中定义的 SAML 客户端的 IDP Initiated SSO URL Name 属性的值。正是此客户端将可用于来自外部 IDP 的 IDP 发起的登录。
-
请注意,您可以将基本客户端设置从代理 IDP 导入到外部 IDP 的客户端设置中 - 只需使用代理 IDP 中身份提供程序的设置中提供的 SP 描述符,并将 clients/client-id
添加到端点 URL。
客户端链接
为了从一个客户端链接到另一个客户端,Keycloak 提供了一个重定向端点:/realms/realm_name/clients/{client-id}/redirect
。
如果客户端使用 HTTP GET
请求访问此端点,则 Keycloak 以 HTTP 307
(临时重定向)的形式在响应的 Location
标头中返回为提供的客户端和 Realm 配置的基本 URL。因此,客户端只需要知道 Realm 名称和客户端 ID 即可链接到它们。这种间接方式避免了硬编码客户端基本 URL。
例如,给定 realm master
和客户端 ID account
http://host:port/realms/master/clients/account/redirect
此 URL 临时重定向到:http://host:port/realms/master/account
OIDC 令牌和 SAML 断言映射
接收 ID 令牌、访问令牌或 SAML 断言的应用程序可能需要不同的角色和用户元数据。
您可以使用 Keycloak 来
-
硬编码角色、声明和自定义属性。
-
将用户元数据拉入令牌或断言。
-
重命名角色。
您可以在管理控制台的**映射器**选项卡中执行这些操作。
新客户端没有内置映射器,但它们可以从客户端作用域继承一些映射器。有关更多详细信息,请参阅 客户端作用域部分。
协议映射器将项目(例如电子邮件地址)映射到身份和访问令牌中的特定声明。映射器的功能应该从其名称中不言自明。您可以通过单击**添加内置**来添加预配置的映射器。
每个映射器都有一组通用设置。其他设置取决于映射器类型。单击映射器旁边的**编辑**以访问配置屏幕来调整这些设置。
可以通过将鼠标悬停在其工具提示上来查看每个选项的详细信息。
您可以使用大多数 OIDC 映射器来控制声明的放置位置。您可以选择通过调整**添加到 ID 令牌**和**添加到访问令牌**开关,将声明包含在 id 和 access 令牌中或从中排除。
您可以按如下方式添加映射器类型
-
转到**映射器**选项卡。
-
单击**配置新映射器**。
添加映射器 -
从列表框中选择**映射器类型**。
优先级顺序
映射器实现具有优先级顺序。优先级顺序不是映射器的配置属性。它是映射器具体实现的属性。
Mapper 按照 mapper 列表中的顺序排序。令牌或断言中的更改按照此顺序应用,顺序靠前的 mapper 先应用。因此,依赖于其他实现的实现会按照必要的顺序进行处理。
例如,要计算将包含在令牌中的角色
-
基于这些角色解析受众。
-
处理 JavaScript 脚本,该脚本使用令牌中已有的角色和受众。
OIDC 用户会话备注 Mapper
用户会话详细信息使用 mapper 定义,并在您在客户端上使用或启用功能时自动包含。单击添加内置以包含会话详细信息。
模拟用户会话提供以下详细信息
-
IMPERSONATOR_ID:模拟用户的 ID。
-
IMPERSONATOR_USERNAME:模拟用户的用户名。
服务帐户会话提供以下详细信息
-
clientId:服务帐户的客户端 ID。
-
client_id:服务帐户的客户端 ID。
-
clientAddress:服务帐户的已验证设备的远程主机 IP。
-
clientHost:服务帐户的已验证设备的远程主机名。
脚本 Mapper
使用脚本 Mapper 通过运行用户定义的 JavaScript 代码将声明映射到令牌。有关将脚本部署到服务器的更多详细信息,请参阅JavaScript 提供程序。
当脚本部署后,您应该能够从可用 mapper 列表中选择已部署的脚本。
成对主体标识符 Mapper
默认情况下,主体声明 sub 由默认客户端作用域 basic 中的 Subject (sub) 协议 Mapper 映射。
要使用成对主体标识符(通过使用诸如 Pairwise subject identifier 之类的协议 Mapper),您可以从 basic 客户端作用域中删除 Subject (sub) 协议 Mapper。但这并非严格必要,因为 Subject (sub) 协议 Mapper 在 Pairwise subject identifier Mapper 之前执行,因此成对值将覆盖 Subject Mapper 添加的值。这是由于 Subject Mapper 的优先级。因此,删除内置的 Subject (sub) Mapper 的唯一优势可能是通过避免使用协议 Mapper 来节省少量性能,但这可能没有任何效果。
使用轻量级访问令牌
Keycloak 中的访问令牌包含敏感信息,包括个人身份信息 (PII)。因此,如果资源服务器不想向客户端等第三方实体泄露此类信息,Keycloak 支持从访问令牌中删除 PII 的轻量级访问令牌。此外,当资源服务器获取从访问令牌中删除的 PII 时,它可以通过将访问令牌发送到 Keycloak 的令牌自省端点来获取 PII。
- 无法从轻量级访问令牌中删除的信息
-
协议 Mapper 可以控制哪些信息放入访问令牌,轻量级访问令牌也使用协议 Mapper。因此,以下信息无法从轻量级访问令牌中删除。
exp
、iat
、jti
、iss
、typ
、azp
、sid
、scope
、cnf
- 在 Keycloak 中使用轻量级访问令牌
-
通过将 客户端策略 的
use-lightweight-access-token
执行器应用于客户端,客户端可以接收轻量级访问令牌而不是访问令牌。轻量级访问令牌包含由协议 Mapper 控制的声明,其设置添加到轻量级访问令牌(默认为关闭)已开启。此外,通过开启协议 Mapper 的设置添加到令牌自省,客户端可以通过将访问令牌发送到 Keycloak 的令牌自省端点来获取声明。 - 自省端点
-
在某些情况下,使用 HTTP 标头
Accept: application/jwt
而不是Accept: application/json
触发令牌自省端点可能很有用,这对于轻量级访问令牌尤其有用。有关令牌自省端点的详细信息,请参阅保护应用部分。
生成客户端适配器配置
Keycloak 可以生成配置文件,您可以使用这些文件在应用程序的部署环境中安装客户端适配器。OIDC 和 SAML 支持多种适配器类型。
-
单击操作菜单,然后选择 下载适配器配置 选项
-
选择您要为其生成配置的 格式选项。
支持所有用于 OIDC 和 SAML 的 Keycloak 客户端适配器。mod-auth-mellon Apache HTTPD 适配器(用于 SAML)以及标准 SAML 实体描述符文件也受支持。
客户端作用域
客户端作用域还支持 OAuth 2 scope 参数。客户端应用程序使用此参数来请求访问令牌中的声明或角色,具体取决于应用程序的需求。
要创建客户端作用域,请按照以下步骤操作
-
在菜单中单击 客户端作用域。
客户端作用域列表 -
单击“创建”。
-
命名您的客户端作用域。
-
点击 保存。
协议
创建客户端作用域时,选择协议。链接到同一作用域的客户端必须具有相同的协议。
每个 realm 在菜单中都有一组预定义的内置客户端作用域。
-
SAML 协议:role_list。此作用域包含一个用于 SAML 断言中角色列表的协议 Mapper。
-
OpenID Connect 协议:有多个可用的客户端作用域
-
角色
-
web-origins
此作用域也未在 OpenID Connect 规范中定义,并且未添加到访问令牌的 scope 声明中。此作用域用于将允许的 Web 源添加到访问令牌 allowed-origins 声明中。
-
microprofile-jwt
此作用域处理 MicroProfile/JWT 身份验证规范 中定义的声明。此作用域为 upn 声明定义了用户属性 mapper,为 groups 声明定义了 realm 角色 mapper。可以更改这些 mapper,以便可以使用不同的属性来创建 MicroProfile/JWT 特定声明。
-
offline_access
当客户端需要获取离线令牌时,使用此作用域。有关离线令牌的更多详细信息,请参见离线访问部分和OpenID Connect 规范。
-
profile
-
email
-
address
-
phone
-
客户端作用域 profile、email、address 和 phone 在 OpenID Connect 规范 中定义。这些作用域没有定义任何角色作用域映射,但它们确实定义了协议 Mapper。这些 Mapper 对应于 OpenID Connect 规范中定义的声明。
例如,当您打开 phone 客户端作用域并打开 Mapper 选项卡时,您将看到与 phone 作用域规范中定义的声明相对应的协议 Mapper。
当 phone 客户端作用域链接到客户端时,客户端会自动继承 phone 客户端作用域中定义的所有协议 Mapper。为此客户端颁发的访问令牌包含有关用户的电话号码信息,前提是用户已定义电话号码。
内置客户端作用域包含规范中定义的协议 Mapper。您可以自由编辑客户端作用域,并创建、更新或删除任何协议 Mapper 或角色作用域映射。
同意相关设置
客户端作用域包含与同意屏幕相关的选项。如果链接的客户端在客户端上启用了需要同意,则这些选项非常有用。
- 在同意屏幕上显示
-
如果启用了在同意屏幕上显示,并且该作用域已添加到需要同意的客户端,则 同意屏幕文本 中指定的文本将显示在同意屏幕上。此文本在用户通过身份验证后以及在用户从 Keycloak 重定向到客户端之前显示。如果禁用在同意屏幕上显示,则此客户端作用域将不会显示在同意屏幕上。
- 同意屏幕文本
-
当此客户端作用域添加到需要同意的客户端时,同意屏幕上显示的文本默认为客户端作用域的名称。可以使用带有 ${var-name} 字符串的替换变量自定义此文本的值。自定义值在主题中的属性文件中配置。有关自定义的更多信息,请参见服务器开发者指南。
包含在令牌作用域中
客户端作用域上有一个 包含在令牌作用域中 开关。如果打开,则此客户端作用域的名称将添加到访问令牌属性作用域,以及令牌响应和令牌自省端点响应声明 scope
中。如果关闭,则此客户端作用域将从令牌和令牌自省端点响应中省略。如上所述,某些内置客户端作用域已禁用此开关,这意味着即使它们应用于特定请求,也不会包含在 scope
声明中。
将客户端作用域与客户端链接
客户端作用域和客户端之间的链接在客户端的 客户端作用域 选项卡中配置。以下是客户端应用程序 myclient
的外观
客户端作用域和客户端之间有两种链接方式。
- 默认客户端作用域
-
此设置适用于 OpenID Connect 和 SAML 客户端。颁发客户端的 OpenID Connect 令牌或 SAML 断言时,将应用默认客户端作用域。客户端将继承客户端作用域上定义的协议 Mapper 和角色作用域映射。对于 OpenID Connect 协议,无论 OpenID Connect 授权请求中 scope 参数的值如何,始终应用 Mapper 和角色作用域映射。
- 可选客户端作用域
-
此设置仅适用于 OpenID Connect 客户端。仅当 OpenID Connect 授权请求中的 scope 参数请求时,才会在为此客户端颁发令牌时应用可选客户端作用域。
示例
对于此示例,假设客户端已将 profile 和 email 链接为默认客户端作用域,并将 phone 和 address 链接为可选客户端作用域。客户端在向 OpenID Connect 授权端点发送请求时使用 scope 参数的值。
scope=openid phone
scope 参数包含字符串,作用域值用空格分隔。值 openid 是用于所有 OpenID Connect 请求的元值。令牌将包含来自默认客户端作用域 profile 和 email 以及 phone(scope 参数请求的可选客户端作用域)的 mapper 和角色作用域映射。
专用客户端作用域
有一个特殊的客户端作用域,它链接到每个客户端。这是一个专用客户端作用域,当您单击特定客户端的 客户端作用域 选项卡时,它始终显示为第一个客户端作用域。例如,对于客户端 myclient
,客户端作用域显示为 myclient-dedicated
。此客户端作用域表示直接链接到客户端本身的协议 Mapper 和角色作用域映射。
无法从客户端取消链接专用客户端作用域。此外,也无法将此专用客户端作用域链接到其他客户端。换句话说,专用客户端作用域仅适用于特定于单个客户端的协议 Mapper 和角色作用域映射。如果您想在多个客户端之间共享相同的协议 Mapper 配置,通常最好在 realm 选项卡 客户端作用域 中创建一个客户端作用域,然后将此共享客户端作用域链接到每个应应用此共享配置的客户端。
在管理 REST API 和内部 Keycloak 存储中,专用客户端作用域并不作为独立实体存在,因为它的协议映射器和角色作用域映射在内部链接到客户端本身。专用客户端作用域实际上只是管理控制台 UI 的一个抽象概念。 |
评估客户端作用域
映射器 选项卡包含协议映射器,而 作用域 选项卡包含为此客户端声明的角色作用域映射。它们不包含从客户端作用域继承的映射器和作用域映射。可以查看有效的协议映射器(即在客户端本身以及从链接的客户端作用域继承的协议映射器)和在为客户端生成令牌时使用的有效角色作用域映射。
-
单击客户端的 客户端作用域 选项卡。
-
打开子选项卡 评估 。
-
选择要应用的可选客户端作用域。
这将同时显示 scope 参数的值。此参数需要从应用程序发送到 Keycloak OpenID Connect 授权端点。
如果您的应用程序使用 Keycloak JavaScript 适配器,请参阅其章节以了解如何发送具有所需值的 scope 参数。 |
您还可以模拟为此客户端颁发的访问令牌、ID 令牌或 UserInfo 响应对于特定选定用户以及 audience
参数的特定值的外观。请注意,audience
参数目前仅支持令牌交换授权。建议在模拟任何其他授权时将其留空。
所有示例都是为特定用户生成,并为特定客户端颁发,并带有 scope 参数的指定值。这些示例包括使用的所有声明和角色映射。
客户端作用域权限
当向用户颁发令牌时,客户端作用域仅在用户被允许使用它时才适用。
当客户端作用域没有任何角色作用域映射定义时,每个用户都被允许使用此客户端作用域。但是,当客户端作用域定义了角色作用域映射时,用户必须是至少一个角色的成员。用户角色与客户端作用域的角色之间必须存在交集。复合角色会被纳入评估此交集。
如果用户未被允许使用客户端作用域,则在生成令牌时将不会使用任何协议映射器或角色作用域映射。客户端作用域将不会出现在令牌的 scope 值中。
Realm 默认客户端作用域
使用 Realm 默认客户端作用域 来定义自动链接到新创建客户端的客户端作用域集合。
要查看 realm 默认客户端作用域,请单击管理控制台左侧的 客户端作用域 选项卡。在 分配类型 列中,您可以指定特定的客户端作用域应添加为新创建客户端的 默认客户端作用域 还是 可选客户端作用域 。有关 默认 和 可选 客户端作用域的详细信息,请参阅 此节。
创建客户端时,如果需要,您可以取消链接默认客户端作用域。这类似于删除 默认角色。
客户端策略
为了便于保护客户端应用程序的安全,以统一的方式实现以下几点是有益的。
-
设置关于客户端可以拥有的配置的策略
-
客户端配置的验证
-
符合要求的安全标准和配置文件,例如金融级 API (FAPI) 和 OAuth 2.1
为了以统一的方式实现这些点,引入了 客户端策略 的概念。
用例
客户端策略实现了以下几点。
- 设置关于客户端可以拥有的配置的策略
-
客户端上的配置设置可以通过客户端策略在客户端创建/更新期间强制执行,也可以在与特定客户端相关的 OpenID Connect 请求期间对 Keycloak 服务器强制执行。Keycloak 还通过 客户端注册策略 支持类似的功能,该策略在 保护应用程序和服务指南 中的 客户端注册服务 中进行了描述。但是,客户端注册策略只能覆盖 OIDC 动态客户端注册。客户端策略不仅涵盖了客户端注册策略可以做的事情,还涵盖了其他客户端注册和配置方式。目前的计划是用客户端策略取代客户端注册。
- 客户端配置的验证
-
Keycloak 支持验证客户端是否遵循诸如代码交换的 Proof Key、请求对象签名算法、持有者密钥令牌等设置,以及诸如授权端点、令牌端点等端点。这些可以通过每个设置项(在管理控制台上、开关、下拉菜单等)指定。为了使客户端应用程序安全,管理员需要以适当的方式设置许多设置,这使得管理员难以保护客户端应用程序的安全。客户端策略可以执行上述客户端配置的验证,它们也可以用于自动配置某些客户端配置开关以满足高级安全要求。在未来,单个客户端配置设置可能会被直接执行所需验证的客户端策略所取代。
- 符合要求的安全标准和配置文件,例如 FAPI 和 OAuth 2.1
-
全局客户端配置文件 是 Keycloak 中默认预配置的客户端配置文件。它们预先配置为符合标准安全配置文件,例如 保护应用程序 部分中的 FAPI 和 OAuth 2.1 ,这使得管理员可以轻松地保护其客户端应用程序以符合特定的安全配置文件。目前,Keycloak 具有用于支持 FAPI 和 OAuth 2.1 规范的全局配置文件。管理员只需配置客户端策略以指定哪些客户端应符合 FAPI 和 OAuth 2.1。管理员可以配置客户端配置文件和客户端策略,以便可以轻松地使 Keycloak 客户端符合各种其他安全配置文件,例如 SPA、原生应用程序、开放银行等。
协议
客户端策略概念独立于任何特定协议。Keycloak 当前特别支持 OpenID Connect (OIDC) 协议 的客户端配置文件,但也提供了 SAML 协议 的客户端配置文件。
架构
客户端策略由四个构建块组成:条件、执行器、配置文件和策略。
条件
条件确定策略适用于哪个客户端以及何时适用。某些条件在客户端创建/更新时检查,而其他条件在客户端请求期间检查(OIDC 授权请求、令牌端点请求等)。条件检查是否满足指定的标准。例如,某些条件检查客户端的访问类型是否为保密。
条件不能单独使用。它可以在之后描述的 策略 中使用。
条件可以像其他可配置的提供程序一样配置。可以配置什么取决于每个条件的性质。
提供了以下条件
- 创建/更新客户端的方式
-
-
动态客户端注册(匿名或通过初始访问令牌或注册访问令牌进行身份验证)
-
管理 REST API(管理控制台等)
-
例如,在创建客户端时,可以将条件配置为当此客户端由没有初始访问令牌的 OIDC 动态客户端注册(匿名动态客户端注册)创建时评估为 true。因此,此条件可以用于例如确保通过 OIDC 动态客户端注册注册的所有客户端都符合 FAPI 或 OAuth 2.1。
- 客户端的作者(通过是否存在于特定角色或组来检查)
-
在 OpenID Connect 动态客户端注册中,客户端的作者是经过身份验证以获取访问令牌以生成新客户端的最终用户,而不是实际使用访问令牌访问注册端点的现有客户端的服务帐户。通过管理 REST API 进行注册时,客户端的作者是最终用户,例如 Keycloak 的管理员。
- 客户端访问类型(保密、公开、仅持有者)
-
例如,当客户端发送授权请求时,如果此客户端是保密的,则采用策略。保密客户端在启用客户端身份验证时,公开客户端禁用客户端身份验证。仅持有者是一种已弃用的客户端类型。
- 客户端作用域
-
如果客户端具有特定的客户端作用域(作为默认作用域或当前请求中使用的可选作用域),则评估为 true。例如,这可以用于确保具有作用域
fapi-example-scope
的 OIDC 授权请求需要符合 FAPI。 - 客户端角色
-
适用于具有指定名称的客户端角色的客户端。通常,您可以为请求的客户端创建指定名称的客户端角色,并将其用作“标记角色”,以确保指定的客户端策略将应用于请求的客户端。
经常存在对特定客户端(例如 my-client-1 和 my-client-2 )应用特定客户端策略的用例。实现此结果的最佳方法是在您的策略中使用 客户端角色 条件,然后为请求的客户端创建指定名称的客户端角色。此客户端角色可以用作“标记角色”,仅用于标记特定客户端的特定客户端策略。 |
- 客户端域名、主机名或 IP 地址
-
应用于客户端的特定域名。或用于管理员从特定主机名或 IP 地址注册/更新客户端的情况。
- 客户端属性
-
应用于具有指定名称和值的客户端属性的客户端。如果指定多个客户端属性,它们将使用 AND 条件进行评估。如果想要使用 OR 条件进行评估,请多次设置此条件。
- 任何客户端
-
此条件始终评估为 true。例如,它可以用于确保特定 realm 中的所有客户端都符合 FAPI。
- ACR 条件
-
当身份验证请求中请求的 ACR 值与条件中配置的值匹配时应用。例如,它可以用于根据请求的 ACR 值选择身份验证流程。有关更多详细信息,请参阅相关文档和官方 OIDC 规范。
- 授权类型
-
当使用特定的授权类型时,评估结果为 true。例如,它可以与客户端 Scope 结合使用,以在请求特定客户端 Scope 时阻止令牌交换请求。
执行器
执行器指定对采用策略的客户端执行的操作。执行器执行一个或多个指定的操作。例如,某些执行器检查授权请求中参数 redirect_uri
的值是否与授权端点上预先注册的重定向 URI 之一完全匹配,如果不匹配则拒绝此请求。
执行器不能单独使用。它可以在之后描述的配置文件中使用。
执行器可以像其他可配置的提供程序一样进行配置。可以配置的内容取决于每个执行器的性质。
执行器对各种事件起作用。执行器实现可以忽略某些类型的事件(例如,用于检查 OIDC request
对象的执行器仅对 OIDC 授权请求起作用)。事件包括
-
创建客户端(包括通过动态客户端注册创建)
-
更新客户端
-
发送授权请求
-
发送令牌请求
-
发送令牌刷新请求
-
发送令牌撤销请求
-
发送令牌自省请求
-
发送 userinfo 请求
-
发送带有刷新令牌的注销请求(请注意,使用刷新令牌注销是 Keycloak 专有的功能,任何规范都不支持。建议依赖官方 OIDC 注销)。
在每个事件中,执行器可以在多个阶段工作。例如,在创建/更新客户端时,执行器可以通过自动配置特定的客户端设置来修改客户端配置。之后,执行器在验证阶段验证此配置。
此执行器的几个目的之一是实现客户端一致性配置文件(如 FAPI 和 OAuth 2.1)的安全要求。为此,需要以下执行器
-
强制客户端使用安全的 客户端身份验证方法
-
强制使用 持有者密钥令牌
-
强制使用 代码交换证明密钥 (PKCE)
-
强制对 签名 JWT 客户端身份验证(private-key-jwt)使用安全的签名算法
-
强制 HTTPS 重定向 URI,并确保配置的重定向 URI 不包含通配符
-
强制 OIDC
request
对象满足高安全级别 -
强制 OIDC 混合流程的响应类型,包括用作分离签名的 ID 令牌,如 FAPI 1 规范中所述,这意味着从授权响应返回的 ID 令牌将不包含用户个人资料数据
-
强制更安全的
state
和nonce
参数处理,以防止 CSRF -
强制客户端注册时使用更安全的签名算法
-
强制 CIBA 请求使用
binding_message
参数 -
强制 客户端密钥轮换
-
强制客户端注册访问令牌
-
强制检查客户端是否是在使用意图的用例中发出意图的客户端,例如在启动授权码流程以获取访问令牌之前发出意图的 UK OpenBanking
-
强制禁止隐式和混合流程
-
强制检查 PAR 请求是否包含授权请求包含的必要参数
-
强制使用 DPoP 绑定令牌(当启用
dpop
功能时可用) -
强制跳过刷新令牌轮换,并且刷新令牌响应中不返回刷新令牌
-
强制 OAuth 2.1 规范要求的有效重定向 URI
-
强制不能使用 SAML 重定向绑定,或者 SAML 请求和断言已签名
另一个可用的执行器是 auth-flow-enforce
,它可以用于在身份验证请求期间强制执行身份验证流程。例如,它可以用于根据某些条件(例如特定的 scope 或 ACR 值)选择流程。有关更多详细信息,请参阅相关文档。
配置文件
配置文件由多个执行器组成,可以实现 FAPI 和 OAuth 2.1 等安全配置文件。配置文件可以通过 Admin REST API(Admin Console)及其执行器一起配置。存在三个全局配置文件,它们在 Keycloak 中默认配置,并预配置了符合 FAPI 1 Baseline、FAPI 1 Advanced、FAPI CIBA、FAPI 2 和 OAuth 2.1 规范的执行器。更多详细信息请参阅保护应用程序部分中的 FAPI 和 OAuth 2.1。
配置
策略、配置文件、条件、执行器可以通过 Admin REST API 进行配置,这也意味着可以通过 Admin Console 进行配置。为此,有一个选项卡 Realm → Realm Settings → Client Policies,这意味着管理员可以为每个 realm 设置客户端策略。
全局客户端配置文件在每个 realm 中自动可用。但是,默认情况下未配置任何客户端策略。这意味着,如果管理员希望其 realm 的客户端符合 FAPI 标准,则始终需要创建任何客户端策略。全局配置文件无法更新,但管理员可以轻松地将它们用作模板,并在想要对全局配置文件配置进行一些细微更改时创建自己的配置文件。Admin Console 中提供了 JSON 编辑器,这简化了基于某些全局配置文件创建新配置文件的过程。
向后兼容性
客户端策略可以替换 保护应用程序指南中客户端注册服务中描述的客户端注册策略。但是,客户端注册策略仍然共存。这意味着,例如,在动态客户端注册请求以创建/更新客户端期间,客户端策略和客户端注册策略都会被应用。
目前的计划是删除客户端注册策略功能,现有的客户端注册策略将自动迁移到新的客户端策略中。
客户端密钥轮换示例
请参阅客户端密钥轮换的示例配置。
将 Keycloak 配置为可验证凭证颁发者
这是一个实验性功能,不应在生产环境中使用。不保证向后兼容性,并且未来的更新可能会引入破坏性更改。 |
Keycloak 为 OpenID for Verifiable Credential Issuance 提供实验性支持。
简介
本章提供将 Keycloak 配置为使用 OpenID for Verifiable Credential Issuance (OID4VCI) 协议的可验证凭证颁发者的分步说明。它概述了设置 Keycloak 实例以安全地颁发和管理可验证凭证 (VC) 的过程,从而支持去中心化身份解决方案。
什么是可验证凭证 (VC)?
可验证凭证 (VC) 是加密签名的、防篡改的数据结构,表示关于实体(例如个人、组织或设备)的声明。它们是去中心化身份系统的基础,允许安全且保护隐私的身份验证,而无需依赖中心化机构。VC 支持选择性披露和零知识证明等高级功能,从而增强用户隐私和安全性。
什么是 OID4VCI?
OpenID for Verifiable Credential Issuance (OID4VCI) 是 OpenID Connect (OIDC) 协议的扩展。它定义了一个标准化的、可互操作的框架,供凭证颁发者向持有者交付 VC,然后持有者可以将它们呈现给验证者。OID4VCI 利用 Keycloak 现有的身份验证和授权功能来简化 VC 颁发。
本章范围
本章涵盖以下技术配置
-
为 VC 颁发创建专用 realm。
-
设置测试用户以进行凭证测试。
-
配置自定义加密密钥以用于签名和加密 VC。
-
定义 realm 属性以指定 VC 元数据。
-
建立客户端 scope 和映射器,以在 VC 中包含用户属性。
-
注册客户端以处理 VC 请求。
-
配置凭证构建器以进行 VC 格式化。
-
使用颁发者元数据端点验证配置。
Keycloak 实例
运行中的 Keycloak 服务器,并已启用 OID4VCI 功能。
要启用该功能,请将以下标志添加到启动命令
--features=oid4vc-vci
通过检查服务器日志中是否有 OID4VC_VCI
初始化消息来验证激活。
创建 Realm
Keycloak 中的 realm 是一个逻辑容器,用于管理用户、客户端、角色和身份验证流程。对于可验证凭证 (VC) 颁发,请创建一个专用 realm 以确保隔离并保持功能的清晰分离。
有关创建 realm 的详细说明,请参阅 Keycloak 文档:创建 Realm。 |
创建用户帐户
需要一个测试用户来模拟凭证颁发并验证设置。
有关创建用户的分步说明,请参阅 Keycloak 文档:创建用户。 |
确保用户具有有效的用户名、电子邮件和密码。如果首次登录时不应重置密码,请在密码配置期间禁用“临时”切换。
密钥管理配置
Keycloak 使用加密密钥来签名和加密可验证凭证 (VC)。为了确保安全且符合标准的颁发,请使用密钥库配置 ECDSA (ES256) 用于签名、RSA (RS256) 用于签名和 RSA-OAEP 用于加密。
有关配置 realm 密钥的详细指南,请参阅 Keycloak 文档:管理 Realm 密钥。 |
配置密钥提供程序
要为 VC 颁发启用加密操作
-
ECDSA (ES256) 密钥:用于使用 ES256 算法对 VC 进行签名。
-
RSA (RS256) 密钥:使用 RS256 的备用签名机制。
-
RSA-OAEP 密钥:用于加密 VC 中的敏感数据。
每个密钥都必须注册为 Realm 设置 > 密钥 部分中的 java-keystore 提供程序,确保: - 密钥库文件已正确指定并安全存储。 - 已选择适当的算法(ES256、RS256 或 RSA-OAEP)。 - 密钥处于活动状态、已启用,并配置了正确的使用方式(签名或加密)。 - 已设置优先级值以定义密钥之间的优先级。
确保密钥库文件安全存储并且 Keycloak 服务器可以访问。使用强密码来保护密钥库和私钥。 |
注册 Realm 属性
Realm 属性定义可验证凭证 (VC) 的元数据,例如过期时间、支持的格式和 scope 定义。这些属性允许 Keycloak 使用预定义设置颁发 VC。
由于 Keycloak Admin Console 不支持直接属性创建,请使用 Keycloak Admin REST API 来配置这些属性。
定义 Realm 属性
创建一个 JSON 文件(例如,realm-attributes.json
),其中包含以下内容
{
"realm": "oid4vc-vci",
"enabled": true,
"preAuthorizedCodeLifespanS": 120,
"issuerDid": "https://#:8443/realms/oid4vc-vci",
"attributes": {
"vc.IdentityCredential.expiry_in_s": "31536000",
"vc.IdentityCredential.format": "vc+sd-jwt",
"vc.IdentityCredential.scope": "identity_credential",
"vc.IdentityCredential.vct": "https://credentials.example.com/identity_credential",
"vc.SteuerberaterCredential.expiry_in_s": "31536000",
"vc.SteuerberaterCredential.format": "vc+sd-jwt",
"vc.SteuerberaterCredential.scope": "stbk_westfalen_lippe",
"vc.SteuerberaterCredential.vct": "stbk_westfalen_lippe",
"vc.SteuerberaterCredential.cryptographic_binding_methods_supported": "jwk"
}
}
这是一个示例配置。您可以根据您的特定需求定义其他属性,例如: - 不同的 VC 类型和 scope。 - 备用凭证格式。 - 自定义加密设置。 |
属性分解
-
preAuthorizedCodeLifespanS – 定义预授权代码保持有效的时间(以秒为单位)。
-
issuerDid – 颁发者的去中心化标识符 (DID)。
-
attributes – 包含 VC 特定的元数据,可以根据需要进行扩展
-
expiry_in_s – 凭证过期时间(以秒为单位)。
-
format – 定义 VC 格式(例如,
vc+sd-jwt
)。 -
scope – 标识凭证的 scope。
-
vct – 可验证凭证类型 (VCT)。
-
cryptographic_binding_methods_supported – 指定支持的加密方法(如果适用)。
导入 Realm 属性
使用以下 curl
命令将属性导入到 Keycloak
curl -X POST "https://#:8443/admin/realms/oid4vc-vci" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @realm-attributes.json
|
创建带有映射器的客户端 Scope
客户端 scope 定义了 哪些用户属性 包含在可验证凭证 (VC) 中。这些 scope 使用协议映射器将特定的声明映射到 VC 中。
由于 Keycloak 管理控制台不支持直接创建带有映射器的客户端作用域,请使用 Keycloak 管理 REST API。
定义带有映射器的客户端作用域
创建一个 JSON 文件(例如,client-scopes.json
),内容如下:
{
"name": "vc-scope-mapping",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "false",
"display.on.consent.screen": "false"
},
"protocolMappers": [
{
"name": "academic_title-mapper-bsk",
"protocol": "oid4vc",
"protocolMapper": "oid4vc-static-claim-mapper",
"config": {
"subjectProperty": "academic_title",
"staticValue": "N/A",
"supportedCredentialTypes": "stbk_westfalen_lippe"
}
}
]
}
这是一个示例配置。您可以定义额外的协议映射器来支持不同的声明映射,例如: - 动态属性值而不是静态属性值。 - 每个凭证类型映射多个属性。 - 替代的支持凭证类型。 |
属性细分
-
name – 客户端作用域的名称。
-
protocol – 对于标准的 OAuth2 工作流程,使用
openid-connect
。 -
attributes – 定义作用域可见性和用户同意行为
-
include.in.token.scope
: 此作用域是否应包含在访问令牌中。 -
display.on.consent.screen
: 是否在用户同意屏幕上显示此作用域。 -
protocolMappers – 定义如何映射声明
-
name – 映射器标识符。
-
protocol – 对于可验证凭据,使用
oid4vc
。 -
protocolMapper – 指定声明映射策略(例如,
oid4vc-static-claim-mapper
)。 -
config:
-
subjectProperty
– 要映射的用户属性。 -
staticValue
– 当属性缺失时分配的静态值。 -
supportedCredentialTypes
– 支持此声明的凭证类型。
导入客户端作用域
使用以下 curl
命令将客户端作用域导入到 Keycloak 中
curl -X POST "https://#:8443/admin/realms/oid4vc-vci/client-scopes" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @client-scopes.json
|
创建 OID4VC 客户端
设置一个客户端来处理 VC 请求,并为其分配必要的作用域。
-
创建一个 JSON 文件(例如,
oid4vc-rest-api-client.json
),内容如下:{ "clientId": "oid4vc-rest-api", "enabled": true, "protocol": "openid-connect", "publicClient": false, "serviceAccountsEnabled": true, "clientAuthenticatorType": "client-secret", "redirectUris": ["https://#:8080/*"], "directAccessGrantsEnabled": true, "defaultClientScopes": ["profile"], "optionalClientScopes": ["vc-scope-mapping"], "attributes": { "client.secret.creation.time": "1719785014", "client.introspection.response.allow.jwt.claim.enabled": "false", "login_theme": "keycloak", "post.logout.redirect.uris": "https://#:8080" } }
-
clientId: 客户端的唯一标识符。
-
optionalClientScopes: 链接用于 VC 请求的
vc-scope-mapping
作用域。
-
-
使用以下
curl
命令导入客户端curl -k -X POST "https://#:8443/admin/realms/oid4vc-vci/clients" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d @oid4vc-rest-api-client.json
创建凭据构建器组件
凭据构建器负责格式化可验证凭据 (VC),例如 SD-JWT。此组件必须使用 Admin REST API 在 Keycloak 中注册。
注册凭据构建器
使用以下 curl
命令来创建凭据构建器
curl -X POST "https://#:8443/admin/realms/oid4vc-vci/components" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "sd-jwt-credentialbuilder",
"providerId": "vc+sd-jwt",
"providerType": "org.keycloak.protocol.oid4vc.issuance.credentialbuilder.CredentialBuilder"
}'
|
验证配置
通过访问颁发者元数据端点来验证设置
-
打开浏览器或使用
curl
等工具访问https://#:8443/realms/oid4vc-vci/.well-known/openid-credential-issuer
成功的响应会返回一个 JSON 对象,其中包含如下详细信息: - 支持的声明 - 凭据格式 - 颁发者元数据
结论
您已使用 OID4VCI 协议成功配置 Keycloak 作为可验证凭据颁发者。此设置利用 Keycloak 强大的身份管理能力来颁发安全的、符合标准的 VC。
有关完整的参考实现,请参阅示例项目: Keycloak SSI Deployment。
使用 Vault 获取密钥
Keycloak 目前提供了 Vault SPI 的两个开箱即用实现:基于纯文本文件的 Vault 和基于 Java KeyStore 的 Vault。
要从 Vault 获取密钥而不是直接输入,请在相应的字段中输入以下特殊构造的字符串
${vault.key}
其中 key
是 Vault 识别的密钥名称。
为了防止密钥跨 realm 泄漏,Keycloak 将 realm 名称与从 Vault 表达式中获取的 key
组合在一起。这种方法意味着 key
不直接映射到 Vault 中的条目,而是根据用于将 key
与 realm 名称组合的算法创建最终的条目名称。对于基于文件的 Vault,这种组合反映为一个特定的文件名,对于基于 Java KeyStore 的 Vault,它是一个特定的别名。
您可以从以下字段中的 Vault 获取密钥
- SMTP 密码
-
在 realm 的 SMTP 设置中
- LDAP 绑定凭据
-
在基于 LDAP 的用户联合的 LDAP 设置中。
- OIDC 身份提供商密钥
-
在身份提供商 OpenID Connect 配置中的客户端密钥内
密钥解析器
所有内置提供程序都支持密钥解析器的配置。密钥解析器实现了将 realm 名称与从 ${vault.key}
表达式中获取的密钥组合成最终条目名称的算法或策略,该最终条目名称用于从 Vault 中检索密钥。Keycloak 使用 keyResolvers
属性来配置提供程序使用的解析器。该值是以逗号分隔的解析器名称列表。以下是 files-plaintext
提供程序的配置示例
kc.[sh|bat] start --spi-vault-file-key-resolvers=REALM_UNDERSCORE_KEY,KEY_ONLY
解析器按照您在配置中声明的顺序运行。对于每个解析器,Keycloak 使用解析器生成的最后一个条目名称,该名称将 realm 与 Vault 密钥组合在一起以搜索 Vault 的密钥。如果 Keycloak 找到密钥,则返回该密钥。否则,Keycloak 使用下一个解析器再次搜索。此搜索将继续进行,直到 Keycloak 找到非空密钥或用完解析器为止。如果 Keycloak 找不到密钥,则 Keycloak 返回空密钥。
在前面的示例中,Keycloak 首先使用 REALM_UNDERSCORE_KEY
解析器。如果 Keycloak 使用该解析器在 Vault 中找到条目,则 Keycloak 返回该条目。否则,Keycloak 使用 KEY_ONLY
解析器再次搜索。如果 Keycloak 通过使用 KEY_ONLY
解析器找到条目,则 Keycloak 返回该条目。如果 Keycloak 使用了所有解析器,则 Keycloak 返回一个空密钥。
以下是当前可用解析器的列表
名称 | 描述 |
---|---|
KEY_ONLY |
Keycloak 忽略 realm 名称,并使用 Vault 表达式中的密钥。Keycloak 使用另一个下划线字符转义密钥中出现的下划线。例如,如果密钥名为 |
REALM_UNDERSCORE_KEY |
Keycloak 通过使用下划线字符组合 realm 和密钥。Keycloak 使用另一个下划线字符转义 realm 或密钥中出现的下划线。例如,如果 realm 名为 |
REALM_FILESEPARATOR_KEY |
Keycloak 通过使用平台文件分隔符字符组合 realm 和密钥。Vault 表达式禁止使用可能导致路径遍历的字符,从而防止访问相应 realm 之外的密钥。 |
FACTORY_PROVIDED |
Keycloak 通过使用 Vault 提供程序工厂的 |
如果您没有为内置提供程序配置解析器,则 Keycloak 将选择 REALM_UNDERSCORE_KEY
。
配置审计以跟踪事件
Keycloak 包含一套审计功能。您可以记录每个登录和管理员操作,并在管理控制台中查看这些操作。Keycloak 还包含一个监听器 SPI,用于监听事件并可以触发操作。内置监听器的示例包括日志文件和在事件发生时发送电子邮件。
审计用户事件
您可以记录和查看每个影响用户的事件。Keycloak 会为诸如用户成功登录、用户输入错误密码或用户帐户更新之类的操作触发登录事件。默认情况下,Keycloak 不会在管理控制台中存储或显示事件。只有错误事件才会记录到管理控制台和服务器的日志文件中。
使用此过程开始审计用户事件。
-
在菜单中单击“Realm 设置”。
-
单击事件选项卡。
-
单击用户事件设置选项卡。
-
将保存事件切换为开启。
用户事件设置 -
在过期时间字段中指定存储事件的时长。
-
单击添加已保存类型以查看您可以保存的其他事件。
添加类型 -
点击 添加。
当您要删除所有已保存的事件时,单击清除用户事件。
您现在可以查看事件了。
-
单击菜单中的事件选项卡。
用户事件 -
要过滤事件,请单击搜索用户事件。
搜索用户事件
事件类型
登录事件
事件 | 描述 |
---|---|
登录 |
用户登录。 |
注册 |
用户注册。 |
注销 |
用户注销。 |
代码到令牌 |
应用程序或客户端将代码交换为令牌。 |
刷新令牌 |
应用程序或客户端刷新令牌。 |
暴力破解保护
事件 | 描述 |
---|---|
用户因永久锁定而被禁用 |
由于登录失败次数过多,暴力破解保护永久禁用了用户帐户。 |
用户因临时锁定而被禁用 |
由于登录失败次数过多,暴力破解保护临时禁用了用户帐户。 |
身份代理
事件 | 描述 |
---|---|
联合身份链接覆盖 |
现有的联合身份链接被覆盖 |
联合身份链接覆盖错误 |
尝试覆盖现有联合身份链接时发生错误 |
OAuth
事件 | 描述 |
---|---|
OAuth2 扩展授权 |
OAuth2 授权已执行 |
OAuth2 扩展授权错误 |
OAuth2 授权执行期间发生错误 |
帐户事件
事件 | 描述 |
---|---|
社交链接 |
用户帐户链接到社交媒体提供商。 |
移除社交链接 |
从社交媒体帐户到用户帐户的链接断开。 |
更新电子邮件 |
帐户的电子邮件地址已更改。 |
更新个人资料 |
帐户的个人资料已更改。 |
发送密码重置 |
Keycloak 发送密码重置电子邮件。 |
更新密码(已弃用) |
帐户的密码已更改。 |
更新凭据 |
帐户的密码或(基于时间的)一次性密码 (OTP/TOTP) 设置已更改。 |
更新 TOTP(已弃用) |
帐户的基于时间的一次性密码 (TOTP) 设置已更改。 |
移除 TOTP(已弃用) |
Keycloak 从帐户中移除 TOTP。 |
移除凭据 |
Keycloak 从帐户中移除凭据。 |
发送验证电子邮件 |
Keycloak 发送电子邮件验证电子邮件。 |
验证电子邮件 |
Keycloak 验证帐户的电子邮件地址。 |
每个事件都有一个相应的错误事件。
事件监听器
事件监听器监听事件并根据该事件执行操作。Keycloak 包括两个内置监听器:日志记录事件监听器和电子邮件事件监听器。
日志记录事件监听器
启用日志记录事件监听器后,当发生错误事件时,此监听器会写入日志文件。
来自日志记录事件监听器的示例日志消息
11:36:09,965 WARN [org.keycloak.events] (default task-51) type=LOGIN_ERROR, realmId=master, clientId=myapp, userId=19aeb848-96fc-44f6-b0a3-59a17570d374, ipAddress=127.0.0.1, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=https://#:8180/myapp, code_id=b669da14-cdbb-41d0-b055-0810a0334607, username=admin
您可以使用日志记录事件监听器来防御黑客机器人攻击
-
解析日志文件以查找
LOGIN_ERROR
事件。 -
提取失败登录事件的 IP 地址。
-
将 IP 地址发送到入侵防御软件框架工具。
日志记录事件监听器将事件记录到 org.keycloak.events
日志类别。默认情况下,Keycloak 不会在服务器日志中包含调试日志事件。
要在服务器日志中包含调试日志事件
-
更改
org.keycloak.events
类别的日志级别 -
更改日志记录事件监听器使用的日志级别。
要更改日志记录事件监听器使用的日志级别,请添加以下内容
bin/kc.[sh|bat] start --spi-events-listener-jboss-logging-success-level=info --spi-events-listener-jboss-logging-error-level=error
日志级别的有效值为 debug
、info
、warn
、error
和 fatal
。
电子邮件事件监听器
当事件发生时,电子邮件事件监听器会向用户的电子邮件地址发送消息,并支持以下事件
-
登录错误。
-
更新密码。
-
更新基于时间的一次性密码 (TOTP)。
-
移除一次性密码 (OTP)。
-
更新凭据。
-
移除凭据。
以下是可以配置的可选事件
-
用户因永久锁定而被禁用。
-
用户因临时锁定而被禁用。
要发送电子邮件,需要满足以下条件
-
用户拥有电子邮件地址。
-
用户的电子邮件地址被标记为已验证。
-
realm 的电子邮件设置已配置。
要启用电子邮件监听器
-
在菜单中单击“Realm 设置”。
-
单击事件选项卡。
-
单击事件监听器字段。
-
选择
email
。事件监听器
您可以使用 --spi-events-listener-email-exclude-events
参数排除事件。例如
kc.[sh|bat] --spi-events-listener-email-exclude-events=UPDATE_CREDENTIAL,REMOVE_CREDENTIAL
要启用可选事件,请使用以下命令
kc.[sh|bat] --spi-events-listener-email-include-events=USER_DISABLED_BY_TEMPORARY_LOCKOUT_ERROR,USER_DISABLED_BY_PERMANENT_LOCKOUT
审计管理员事件
您可以记录管理员在管理控制台中执行的所有操作。管理控制台通过调用 Keycloak REST 接口执行管理操作,而 Keycloak 会审计这些 REST 调用。您可以在管理控制台中查看生成的事件。
使用此步骤开始审计管理员操作。
-
在菜单中单击“Realm 设置”。
-
单击事件选项卡。
-
点击 管理事件设置 选项卡。
-
将保存事件切换为开启。
Keycloak 显示 包含表示 开关。
-
将 包含表示 切换到 开启。
包含表示
开关包含通过管理 REST API 发送的 JSON 文档,以便您可以查看管理员的操作。管理事件设置 -
点击 保存。
-
要清除数据库中存储的操作,请单击 清除管理事件。
您现在可以查看管理事件。
-
点击菜单中的 事件。
-
点击 管理事件 选项卡。
管理事件
当 包含表示
开关处于开启状态时,可能会导致在数据库中存储大量信息。您可以使用 --spi-events-store-jpa-max-field-length
参数设置表示的最大长度。如果您想遵守底层存储限制,此设置非常有用。例如
kc.[sh|bat] --spi-events-store-jpa-max-field-length=2500
缓解安全威胁
任何身份验证服务器都存在安全漏洞。 有关更多信息,请参阅互联网工程任务组 (IETF) 的 OAuth 2.0 威胁模型 和 OAuth 2.0 安全最佳当前实践。
主机
Keycloak 在多种方式中使用公共主机名,例如在令牌颁发者字段和密码重置电子邮件中的 URL 中。
默认情况下,主机名源自请求标头。 没有验证来确保主机名有效。 如果您没有将负载均衡器或代理与 Keycloak 一起使用以防止无效的主机头,请配置可接受的主机名。
主机名的服务提供程序接口 (SPI) 提供了一种为请求配置主机名的方法。 您可以使用此内置提供程序为前端请求设置固定 URL,同时允许基于请求 URI 的后端请求。 如果内置提供程序没有所需的功能,您可以开发自定义提供程序。
暴力攻击
暴力攻击试图通过多次尝试登录来猜测用户的密码。 Keycloak 具有暴力检测功能,如果登录失败次数超过指定阈值,它可以永久或暂时禁用用户帐户。
当用户被锁定并尝试登录时,Keycloak 会显示默认的 |
暴力检测默认情况下处于禁用状态。 启用此功能以防止暴力攻击。 |
要启用此保护
-
点击菜单中的 领域设置
-
单击 安全防御 选项卡。
-
点击 暴力检测 选项卡。
-
选择最适合您需求的 暴力模式。
暴力检测
永久锁定
Keycloak 禁用用户帐户(阻止登录尝试),直到管理员重新启用它。
永久锁定参数
名称 | 描述 | 默认 |
---|---|---|
最大登录失败次数 |
最大登录失败次数。 |
30 次失败 |
快速登录检查毫秒数 |
登录尝试之间的最短时间。 |
1000 毫秒 |
最短快速登录等待时间 |
当登录尝试快于快速登录检查毫秒数时,用户被禁用的最短时间。 |
1 分钟 |
永久锁定流程
-
成功登录时
-
重置
count
-
-
登录失败时
-
增加
count
-
如果
count
大于或等于最大登录失败次数
-
锁定用户
-
-
否则,如果本次失败与上次失败之间的时间小于快速登录检查毫秒数
-
将用户锁定 最短快速登录等待时间 指定的时间
-
-
启用用户帐户会重置 |
临时锁定
Keycloak 会在特定时间段内禁用用户帐户。 随着攻击的持续,帐户被禁用的时间段会增加。
临时锁定参数
名称 | 描述 | 默认 |
---|---|---|
最大登录失败次数 |
最大登录失败次数。 |
30 次失败 |
增加等待时间的策略 |
当用户的登录尝试次数超过最大登录失败次数时,增加用户被临时禁用的时间的策略 |
倍数 |
等待时间增量 |
当用户的登录尝试次数超过最大登录失败次数时,添加到用户被临时禁用的时间的时间。 |
1 分钟 |
最大等待时间 |
用户被临时禁用的最长时间。 |
15 分钟 |
失败重置时间 |
失败计数重置的时间。 计时器从上次登录失败开始运行。 确保此数字始终大于 |
12 小时 |
快速登录检查毫秒数 |
登录尝试之间的最短时间。 |
1000 毫秒 |
最短快速登录等待时间 |
当登录尝试快于快速登录检查毫秒数时,用户被禁用的最短时间。 |
1 分钟 |
临时锁定算法
-
成功登录时
-
重置
count
-
-
登录失败时
-
如果本次失败与上次失败之间的时间大于失败重置时间
-
重置
count
-
-
增加
count
-
根据定义的暴力破解策略计算
wait
(请参阅下面的设置等待时间策略)。 -
如果
wait
小于或等于 0 并且本次失败与上次失败之间的时间小于快速登录检查毫秒数-
将
wait
设置为 最短快速登录等待时间
-
-
如果
wait
大于 0-
将用户临时禁用
wait
和 最大等待时间 秒中的较小值
-
-
当临时禁用的帐户提交登录失败时, |
设置等待时间的策略
Keycloak 提供了两种策略来计算等待时间:倍数或线性。 倍数策略是 Keycloak 最先引入的策略,因此是默认策略。
按倍数策略,当失败次数(或计数)是 最大登录失败次数
的倍数时,等待时间会增加。 例如,如果您将 最大登录失败次数
设置为 5
,并将 等待时间增量
设置为 30
秒,则在多次身份验证尝试失败后,帐户被禁用的有效时间将为
|
|
|
|
1 |
30 |
5 |
0 |
2 |
30 |
5 |
0 |
3 |
30 |
5 |
0 |
4 |
30 |
5 |
0 |
5 |
30 |
5 |
30 |
6 |
30 |
5 |
30 |
7 |
30 |
5 |
30 |
8 |
30 |
5 |
30 |
9 |
30 |
5 |
30 |
10 |
30 |
5 |
60 |
在第五次尝试失败时,帐户将被禁用 30
秒。 在达到 最大登录失败次数
的下一个倍数(在本例中为 10
)后,时间从 30
秒增加到 60
秒。
按倍数策略使用以下公式计算等待时间:等待时间增量(秒) * (count
/ 最大登录失败次数)。 除法是向下舍入为整数的整数除法。
对于线性策略,当失败的 count
(或次数)大于或等于 最大登录失败次数
时,等待时间会增加。 例如,如果您将 最大登录失败次数
设置为 5
,并将 等待时间增量
设置为 30
秒,则在多次身份验证尝试失败后,帐户被禁用的有效时间将为
|
|
|
|
1 |
30 |
5 |
0 |
2 |
30 |
5 |
0 |
3 |
30 |
5 |
0 |
4 |
30 |
5 |
0 |
5 |
30 |
5 |
30 |
6 |
30 |
5 |
60 |
7 |
30 |
5 |
90 |
8 |
30 |
5 |
120 |
9 |
30 |
5 |
150 |
10 |
30 |
5 |
180 |
在第五次尝试失败时,帐户将被禁用 30
秒。 每次新的失败都会根据 等待时间增量
中指定的值增加等待时间。
线性策略使用以下公式计算等待时间:等待时间增量(秒) * (1 + count
- 最大登录失败次数)。
临时锁定后永久锁定
混合模式。 将用户临时锁定指定次数,然后永久锁定用户。
临时锁定后永久锁定参数
名称 | 描述 | 默认 |
---|---|---|
最大登录失败次数 |
最大登录失败次数。 |
30 次失败 |
最大临时锁定次数 |
在发生永久锁定之前允许的最大临时锁定次数。 |
1 |
增加等待时间的策略 |
当用户的登录尝试次数超过最大登录失败次数时,增加用户被临时禁用的时间的策略 |
倍数 |
等待时间增量 |
当用户的登录尝试次数超过最大登录失败次数时,添加到用户被临时禁用的时间的时间。 |
1 分钟 |
最大等待时间 |
用户被临时禁用的最长时间。 |
15 分钟 |
失败重置时间 |
失败计数重置的时间。 计时器从上次登录失败开始运行。 确保此数字始终大于 |
12 小时 |
快速登录检查毫秒数 |
登录尝试之间的最短时间。 |
1000 毫秒 |
最短快速登录等待时间 |
当登录尝试快于快速登录检查毫秒数时,用户被禁用的最短时间。 |
1 分钟 |
临时锁定后永久锁定算法
-
成功登录时
-
重置
count
-
重置
temporary lockout
计数器
-
-
登录失败时
-
如果本次失败与上次失败之间的时间大于失败重置时间
-
重置
count
-
重置
temporary lockout
计数器
-
-
增加
count
-
根据定义的暴力破解策略计算
wait
(请参阅下面的设置等待时间策略)。 -
如果
wait
小于或等于 0 并且本次失败与上次失败之间的时间小于快速登录检查毫秒数-
将
wait
设置为 最短快速登录等待时间 -
将
quick login failure
设置为true
-
-
如果
wait
和最大临时锁定次数
大于 0-
将
wait
设置为wait
和 最大等待时间 秒中的较小值
-
-
如果
quick login failure
为false
-
增加
temporary lockout
计数器
-
-
如果
temporary lockout
计数器超过最大临时锁定次数
-
永久锁定用户
-
-
否则
-
根据
wait
值临时阻止用户
-
-
当临时禁用的帐户提交登录失败时, |
密码策略
确保您具有复杂的密码策略,以强制用户选择复杂的密码。 有关更多信息,请参阅 密码策略 章节。 通过设置 Keycloak 服务器以使用一次性密码来防止密码猜测。
只读用户属性
存储在 Keycloak 中的典型用户具有与其用户个人资料相关的各种属性。 这些属性包括电子邮件、名字或姓氏。 但是,用户也可能具有属性,这些属性不是典型的个人资料数据,而是元数据。 元数据属性通常对于用户应该是只读的,并且典型用户永远不应能够通过 Keycloak 用户界面或帐户 REST API 更新这些属性。 某些属性甚至对于管理员在通过管理 REST API 创建或更新用户时也应该是只读的。
元数据属性通常是以下组中的属性
-
与用户存储提供程序相关的各种链接或元数据。 例如,在 LDAP 集成的情况下,
LDAP_ID
属性包含用户在 LDAP 服务器中的 ID。 -
用户存储提供的元数据。 例如,从 LDAP 提供的
createdTimestamp
应该始终对用户或管理员只读。 -
与各种认证器相关的元数据。例如,
KERBEROS_PRINCIPAL
属性可以包含特定用户的 Kerberos 主体名称。类似地,usercertificate
属性可以包含与用户和 X.509 证书中的数据绑定的元数据,这通常在启用 X.509 证书身份验证时使用。 -
与应用程序/客户端的用户标识符相关的元数据。例如,
saml.persistent.name.id.for.my_app
可以包含 SAML NameID,客户端应用程序my_app
将使用它作为用户标识符。 -
与授权策略相关的元数据,这些策略用于基于属性的访问控制 (ABAC)。这些属性的值可能用于授权决策。因此,重要的是用户无法更新这些属性。
从长远来看,Keycloak 将拥有一个适当的用户配置文件 SPI,这将允许对每个用户属性进行细粒度的配置。目前,此功能尚未完全可用。因此,Keycloak 具有内部用户属性列表,这些属性对于用户是只读的,对于在服务器级别配置的管理员也是只读的。
这是只读属性的列表,Keycloak 默认提供程序和功能在内部使用这些属性,因此始终是只读的
-
对于用户:
KERBEROS_PRINCIPAL
,LDAP_ID
,LDAP_ENTRY_DN
,CREATED_TIMESTAMP
,createTimestamp
,modifyTimestamp
,userCertificate
,saml.persistent.name.id.for.*
,ENABLED
,EMAIL_VERIFIED
-
对于管理员:
KERBEROS_PRINCIPAL
,LDAP_ID
,LDAP_ENTRY_DN
,CREATED_TIMESTAMP
,createTimestamp
,modifyTimestamp
系统管理员有一种方法可以向此列表添加其他属性。该配置目前在服务器级别可用。
您可以使用 spi-user-profile-declarative-user-profile-read-only-attributes
和 spi-user-profile-declarative-user-profile-admin-read-only-attributes
选项添加此配置。例如
kc.[sh|bat] start --spi-user-profile-declarative-user-profile-read-only-attributes=foo,bar*
对于此示例,用户和管理员将无法更新属性 foo
。用户将无法编辑任何以 bar
开头的属性。例如 bar
或 barrier
。配置不区分大小写,因此对于此示例,类似 FOO
或 BarRier
的属性也将被拒绝。通配符 *
仅在属性名称末尾受支持,因此管理员可以有效地拒绝所有以指定字符开头的属性。属性名称中间的 *
被视为普通字符。
验证用户属性
借助 管理用户属性 中的功能,管理员可以限制用户为属性输入的数据,例如,在用户注册或帐户控制台中。
管理员不应允许用户使用非托管属性,以防止攻击者添加无限数量的属性。属性应具有验证,以限制攻击者输入的数据量。
当使用正则表达式验证用户属性时,请避免使用占用过多内存或 CPU 的正则表达式。有关详细信息,请参阅 OWASP 的正则表达式拒绝服务。
点击劫持
点击劫持是一种欺骗用户点击与用户感知到的用户界面元素不同的技术。恶意站点将目标站点加载到透明的 iFrame 中,该 iFrame 覆盖在目标站点上重要按钮正下方的一组虚拟按钮之上。当用户单击可见按钮时,他们实际上单击的是隐藏页面上的按钮。攻击者可以使用此方法窃取用户的身份验证凭据并访问其资源。
默认情况下,Keycloak 的每个响应都会设置一些特定的 HTTP 标头,以防止这种情况发生。具体来说,它设置了 X-Frame-Options 和 Content-Security-Policy。您应该查看这两个标头的定义,因为您可以控制许多细粒度的浏览器访问。
在管理控制台中,您可以指定 X-Frame-Options 和 Content-Security-Policy 标头的值。
-
单击领域设置菜单项。
-
单击 安全防御 选项卡。
安全防御
默认情况下,Keycloak 仅为 iframe 设置 同源 策略。
SSL/HTTPS 要求
OAuth 2.0/OpenID Connect 使用访问令牌进行安全保护。攻击者可以扫描您的网络以查找访问令牌,并使用它们执行令牌具有权限的恶意操作。这种攻击被称为中间人攻击。在 Keycloak 身份验证服务器和 Keycloak 保护的客户端之间的通信中使用 SSL/HTTPS,以防止中间人攻击。
Keycloak 具有 三种 SSL/HTTPS 模式。SSL 设置起来很复杂,因此 Keycloak 允许通过私有 IP 地址(例如 localhost、192.168.x.x 和其他私有 IP 地址)进行非 HTTPS 通信。在生产环境中,请确保启用 SSL,并且 SSL 对于所有操作都是强制性的。
在适配器/客户端侧,您可以禁用 SSL 信任管理器。信任管理器确保 Keycloak 通信的客户端身份有效,并确保 DNS 域名与服务器证书一致。在生产环境中,请确保您的每个客户端适配器都使用信任存储,以防止 DNS 中间人攻击。
CSRF 攻击
跨站请求伪造 (CSRF) 攻击使用来自网站已验证用户的 HTTP 请求。任何使用基于 Cookie 的身份验证的站点都容易受到 CSRF 攻击。您可以通过将状态 Cookie 与发布的表单或查询参数进行匹配来缓解这些攻击。
OAuth 2.0 登录规范要求状态 Cookie 与传输的状态参数匹配。Keycloak 完全实现了规范的这一部分,因此所有登录都受到保护。
Keycloak 管理控制台是一个 JavaScript/HTML5 应用程序,它对后端 Keycloak 管理 REST API 进行 REST 调用。这些调用都需要持有者令牌身份验证,并且由 JavaScript Ajax 调用组成,因此 CSRF 是不可能的。您可以配置管理 REST API 以验证 CORS 来源。
Keycloak 中的帐户控制台可能容易受到 CSRF 攻击。为了防止 CSRF 攻击,Keycloak 设置了一个状态 Cookie,并将此 Cookie 的值嵌入到操作链接中的隐藏表单字段或查询参数中。Keycloak 检查查询/表单参数与状态 Cookie,以验证是否是同一用户发起的调用。
不明确的重定向 URI
使您注册的重定向 URI 尽可能具体。为 授权码流程 注册模糊的重定向 URI 可能会允许恶意客户端冒充另一个具有更广泛访问权限的客户端。例如,如果两个客户端位于同一域名下,则可能发生冒充。
您可以为您的领域使用安全重定向 uri 执行器。结果确保客户端管理员只能注册具有特定重定向 uri 的客户端,这些 uri 符合各种要求,例如要求 URL 在上下文路径中不能有通配符,或者可以限制为指定的允许域。有关如何使用特定执行器配置客户端策略的详细信息,请参阅 客户端策略。
FAPI 合规性
为了确保 Keycloak 服务器将验证您的客户端是否更安全且符合 FAPI,您可以为 FAPI 支持配置客户端策略。FAPI 详细信息在 保护应用程序 部分中描述。除其他事项外,这确保了一些上述安全最佳实践,例如客户端所需的 SSL、使用的安全重定向 URI 以及更多类似的最佳实践。
OAuth 2.1 合规性
为了确保 Keycloak 服务器将验证您的客户端是否更安全且符合 OAuth 2.1,您可以为 OAuth 2.1 支持配置客户端策略。OAuth 2.1 详细信息在 保护应用程序 部分中描述。
泄露的访问令牌和刷新令牌
Keycloak 包含多项操作,以防止恶意行为者窃取访问令牌和刷新令牌。关键操作是强制 Keycloak 与其客户端和应用程序之间的 SSL/HTTPS 通信。默认情况下,Keycloak 不启用 SSL。
缓解泄露的访问令牌造成的损害的另一项操作是缩短令牌的生命周期。您可以在 超时页面 中指定令牌生命周期。访问令牌的短生命周期迫使客户端和应用程序在短时间后刷新其访问令牌。如果管理员检测到泄漏,则管理员可以注销所有用户会话以使这些刷新令牌无效,或设置撤销策略。
确保刷新令牌始终对客户端保持私有,并且永远不会被传输。
您可以通过将这些令牌作为持有者密钥令牌颁发来减轻泄露的访问令牌和刷新令牌造成的损害。有关更多信息,请参阅 OAuth 2.0 相互 TLS 客户端证书绑定访问令牌。
如果访问令牌或刷新令牌泄露,请访问管理控制台并将不早于撤销策略推送到所有应用程序。推送不早于策略可确保在该时间之前颁发的任何令牌都变为无效。推送新的不早于策略可确保应用程序必须从 Keycloak 下载新的公钥,并减轻来自泄露的领域签名密钥的损害。有关更多信息,请参阅 密钥章节。
如果特定应用程序、客户端或用户遭到泄露,您可以禁用它们。
泄露的授权码
对于 OIDC 授权码流程,Keycloak 为其授权码生成加密强度高的随机值。授权码仅使用一次以获取访问令牌。
在管理控制台的超时页面上,您可以指定授权码的有效时长。确保时长少于 10 秒,这足以让客户端从代码请求令牌。
您还可以通过对客户端应用 代码交换的 Proof Key (PKCE) 来防御泄露的授权码。
开放重定向器
开放重定向器是一个端点,它使用参数自动将用户代理重定向到参数值指定的位置,而无需验证。攻击者可以使用最终用户授权端点和重定向 URI 参数,将授权服务器用作开放重定向器,利用用户对授权服务器的信任来发起网络钓鱼攻击。
Keycloak 要求所有注册的应用程序和客户端至少注册一个重定向 URI 模式。当客户端请求 Keycloak 执行重定向时,Keycloak 会根据有效注册的 URI 模式列表检查重定向 URI。客户端和应用程序必须注册尽可能具体的 URI 模式,以缓解开放重定向器攻击。
如果应用程序需要非 http(s) 自定义方案,则它应是验证模式的显式部分(例如 custom:/app/*
)。出于安全原因,像 *
这样的通用模式不涵盖非 http(s) 方案。
通过使用 客户端策略,管理员可以确保客户端无法注册开放重定向 URL,例如 *
。
密码数据库泄露
Keycloak 不以原始文本形式存储密码,而是以哈希文本形式存储,使用 PBKDF2-HMAC-SHA512
消息摘要算法。Keycloak 执行 210,000
次哈希迭代,这是安全社区推荐的迭代次数。如此多的哈希迭代次数可能会对性能产生不利影响,因为 PBKDF2 哈希会使用大量的 CPU 资源。
限制令牌受众
在服务之间信任度较低的环境中,限制令牌上的受众。有关更多信息,请参阅 OAuth2 威胁模型 和 受众支持 部分。
限制身份验证会话
身份验证会话跟踪身份验证的状态。以下文本适用于任何来源流程。
本节介绍使用 Infinispan 提供程序进行身份验证会话的部署。 |
身份验证会话在内部存储为 RootAuthenticationSessionEntity
。每个 RootAuthenticationSessionEntity
可以在 RootAuthenticationSessionEntity
中存储多个身份验证子会话,作为 AuthenticationSessionEntity
对象的集合。Keycloak 将身份验证会话存储在专用的 Infinispan 缓存中。每个 RootAuthenticationSessionEntity
的 AuthenticationSessionEntity
数量会影响每个缓存条目的大小。身份验证会话缓存的总内存占用由存储的 RootAuthenticationSessionEntity
数量以及每个 RootAuthenticationSessionEntity
中 AuthenticationSessionEntity
的数量决定。
维护的 RootAuthenticationSessionEntity
对象数量对应于来自浏览器的未完成登录流程的数量。为了控制 RootAuthenticationSessionEntity
的数量,建议使用高级防火墙控制来限制入口网络流量。
对于存在许多活动的 RootAuthenticationSessionEntity
和大量 AuthenticationSessionEntity
的部署,可能会出现更高的内存使用率。如果负载均衡器不支持或未配置会话粘性,则集群中网络上的负载可能会显着增加。此负载的原因是,每个落在不拥有相应身份验证会话的节点上的请求都需要在所有者节点中检索和更新身份验证会话记录,这涉及检索和存储的单独网络传输。
每个 RootAuthenticationSessionEntity
的最大 AuthenticationSessionEntity
数量可以在 authenticationSessions
SPI 中通过设置属性 authSessionsLimit
进行配置。默认值设置为每个 RootAuthenticationSessionEntity
300 个 AuthenticationSessionEntity
。当达到此限制时,在新的身份验证会话请求后,将删除最旧的身份验证子会话。
以下示例显示如何将每个 RootAuthenticationSessionEntity
的活动 AuthenticationSessionEntity
数量限制为 100。
bin/kc.[sh|bat] start --spi-authentication-sessions-infinispan-auth-sessions-limit=100
新映射存储的等效命令
bin/kc.[sh|bat] start --spi-authentication-sessions-map-auth-sessions-limit=100
账户控制台
Keycloak 用户可以通过账户控制台管理他们的账户。他们可以配置个人资料、添加双因素身份验证、包含身份提供商账户以及监督设备活动。
-
账户控制台可以在外观和语言偏好方面进行配置。一个示例是将其他属性添加到个人信息页面。有关更多信息,请参阅服务器开发者指南。
访问账户控制台
-
记下您的账户所在的 Keycloak 服务器的 realm 名称和 IP 地址。
-
在 Web 浏览器中,输入此格式的 URL:server-root/realms/{realm-name}/account。
-
输入您的登录名和密码。
您还可以在调用账户控制台 URL 时通过设置 scope
参数来请求其他范围,格式如下:server-root/realms/{realm-name}/account?scope=phone。
配置登录方式
您可以使用基本身份验证(登录名和密码)或双因素身份验证登录此控制台。对于双因素身份验证,请使用以下步骤之一。
使用 OTP 进行双因素身份验证
-
OTP 是您的 realm 的有效身份验证机制。
-
单击菜单中的账户安全。
-
单击登录。
-
单击设置 Authenticator 应用程序。
登录 -
按照屏幕上出现的指示使用您的移动设备作为您的 OTP 生成器。
-
将屏幕截图中的 QR 码扫描到您移动设备上的 OTP 生成器中。
-
注销并重新登录。
-
通过输入您的移动设备上提供的 OTP 来响应提示。
使用 WebAuthn 进行双因素身份验证
-
WebAuthn 是您的 realm 的有效双因素身份验证机制。请关注 WebAuthn 部分以了解更多详情。
-
单击菜单中的账户安全。
-
单击登录。
-
单击设置通行密钥。
登录 -
准备您的通行密钥。如何准备此密钥取决于您使用的通行密钥类型。例如,对于基于 USB 的 Yubikey,您可能需要将密钥插入笔记本电脑上的 USB 端口。
-
单击注册以注册您的通行密钥。
-
注销并重新登录。
-
假设身份验证流程设置正确,则会出现一条消息,要求您使用通行密钥作为第二因素进行身份验证。
使用 WebAuthn 进行无密码身份验证
-
WebAuthn 是您的 realm 的有效无密码身份验证机制。请关注 无密码 WebAuthn 部分以了解更多详情。
-
单击菜单中的账户安全。
-
单击登录。
-
在无密码部分中,单击设置通行密钥。
登录 -
准备您的通行密钥。如何准备此密钥取决于您使用的通行密钥类型。例如,对于基于 USB 的 Yubikey,您可能需要将密钥插入笔记本电脑上的 USB 端口。
-
单击注册以注册您的通行密钥。
-
注销并重新登录。
-
假设身份验证流程设置正确,则会出现一条消息,要求您使用通行密钥作为第二因素进行身份验证。您不再需要提供密码即可登录。
添加身份提供商账户
您可以将您的账户与身份代理链接。此选项通常用于链接社交提供商账户。
-
登录到管理控制台。
-
单击菜单中的身份提供商。
-
选择提供商并填写字段。
-
返回到账户控制台。
-
单击菜单中的账户安全。
-
单击关联账户。
您添加的身份提供商将出现在此页面中。
Admin CLI
借助 Keycloak,您可以使用 Admin CLI 命令行工具从命令行界面 (CLI) 执行管理任务。
安装 Admin CLI
Keycloak 将 Admin CLI 服务器发行包与 bin
目录中的执行脚本打包在一起。
Linux 脚本称为 kcadm.sh
,Windows 脚本称为 kcadm.bat
。将 Keycloak 服务器目录添加到您的 PATH
,以便从文件系统上的任何位置使用客户端。
例如
-
Linux
$ export PATH=$PATH:$KEYCLOAK_HOME/bin $ kcadm.sh
-
Windows
c:\> set PATH=%PATH%;%KEYCLOAK_HOME%\bin c:\> kcadm
您必须将 为避免重复,本文档的其余部分仅在 CLI 差异不仅仅在于 |
使用 Admin CLI
Admin CLI 向 Admin REST 端点发出 HTTP 请求。访问 Admin REST 端点需要身份验证。
有关特定端点的 JSON 属性的详细信息,请参阅 Admin REST API 文档。 |
-
通过登录启动经过身份验证的会话。现在,您可以执行创建、读取、更新和删除 (CRUD) 操作。
例如
-
Linux
$ kcadm.sh config credentials --server https://#:8080 --realm demo --user admin --client admin $ kcadm.sh create realms -s realm=demorealm -s enabled=true -o $ CID=$(kcadm.sh create clients -r demorealm -s clientId=my_client -s 'redirectUris=["https://#:8980/myapp/*"]' -i) $ kcadm.sh get clients/$CID/installation/providers/keycloak-oidc-keycloak-json
-
Windows
c:\> kcadm config credentials --server https://#:8080 --realm demo --user admin --client admin c:\> kcadm create realms -s realm=demorealm -s enabled=true -o c:\> kcadm create clients -r demorealm -s clientId=my_client -s "redirectUris=[\"https://#:8980/myapp/*\"]" -i > clientid.txt c:\> set /p CID=<clientid.txt c:\> kcadm get clients/%CID%/installation/providers/keycloak-oidc-keycloak-json
-
-
在生产环境中,请使用
https:
访问 Keycloak,以避免泄露令牌。如果 Java 默认证书信任存储中包含的受信任证书颁发机构未颁发服务器证书,请准备一个truststore.jks
文件,并指示 Admin CLI 使用它。例如
-
Linux
$ kcadm.sh config truststore --trustpass $PASSWORD ~/.keycloak/truststore.jks
-
Windows
c:\> kcadm config truststore --trustpass %PASSWORD% %HOMEPATH%\.keycloak\truststore.jks
-
敏感选项
敏感值(如密码)可以指定为命令选项。通常不建议这样做。还有一些机制,您可以通过省略选项或提供值来提示您输入敏感值。最后,所有这些都将有一个相应的环境变量可以代替使用。查看您正在运行的命令的帮助信息,以查看所有可能的选项。
身份验证
当您使用 Admin CLI 登录时,您需要指定
-
服务器端点 URL
-
域
-
用户名
另一个选项是仅指定 clientId,这将为您创建一个唯一的服务帐户供您使用。
当您使用用户名登录时,请使用指定用户的密码。当您使用 clientId 登录时,您只需要客户端密钥,而不需要用户密码。您也可以使用 Signed JWT
而不是客户端密钥。
确保用于会话的帐户具有调用 Admin REST API 操作的适当权限。例如,realm-management
客户端的 realm-admin
角色可以管理用户的域。
有两种主要的身份验证机制可用。一种机制使用 kcadm config credentials
启动经过身份验证的会话。
$ kcadm.sh config credentials --server https://#:8080 --realm master --user admin
此机制通过保存获得的访问令牌及其关联的刷新令牌,在 kcadm
命令调用之间维护经过身份验证的会话。它可以将其他密钥保存在私有配置文件中。有关更多信息,请参阅下一章。
第二种机制在每次命令调用期间进行身份验证,用于该调用的持续时间。此机制会增加服务器的负载以及花费在往返获取令牌上的时间。这种方法的好处是不需要在调用之间保存令牌,因此不会保存到磁盘。当指定 --no-config
参数时,Keycloak 使用此模式。
例如,在执行操作时,请指定身份验证所需的所有信息。
$ kcadm.sh get realms --no-config --server https://#:8080 --realm master --user admin
运行 kcadm.sh help
命令,以获取有关使用 Admin CLI 的更多信息。
运行 kcadm.sh config credentials --help
命令,以获取有关启动经过身份验证的会话的更多信息。
如果您未指定 --password 选项(通常建议不要将密码作为命令的一部分提供),除非已将密码指定为环境变量 KC_CLI_PASSWORD,否则系统将提示您输入密码。
使用备用配置
默认情况下,Admin CLI 维护一个名为 kcadm.config
的配置文件。Keycloak 将此文件放置在用户的主目录中。在基于 Linux 的系统中,完整路径名为 $HOME/.keycloak/kcadm.config
。在 Windows 中,完整路径名为 %HOMEPATH%\.keycloak\kcadm.config
。
您可以使用 --config
选项指向不同的文件或位置,以便您可以并行维护多个经过身份验证的会话。
从单个线程执行与单个配置文件绑定的操作。 |
确保配置文件对系统上的其他用户不可见。它包含必须保密的访问令牌和密钥。Keycloak 会自动创建 ~/.keycloak
目录及其内容,并具有适当的访问限制。如果目录已存在,Keycloak 不会更新目录的权限。
可以避免将密钥存储在配置文件中,但这很不方便,并且会增加令牌请求的数量。将 --no-config
选项与所有命令一起使用,并在每次调用 kcadm
时指定 config credentials
命令所需的身份验证信息。
基本操作和资源 URI
Admin CLI 可以通用地对 Admin REST API 端点执行 CRUD 操作,并提供简化特定任务的附加命令。
主要使用模式在此处列出
$ kcadm.sh create ENDPOINT [ARGUMENTS] $ kcadm.sh get ENDPOINT [ARGUMENTS] $ kcadm.sh update ENDPOINT [ARGUMENTS] $ kcadm.sh delete ENDPOINT [ARGUMENTS]
create
、get
、update
和 delete
命令分别映射到 HTTP 动词 POST
、GET
、PUT
和 DELETE
。ENDPOINT 是目标资源 URI,可以是绝对的(以 http:
或 https:
开头)或相对的,Keycloak 使用它来组合以下格式的绝对 URL
SERVER_URI/admin/realms/REALM/ENDPOINT
例如,如果您针对服务器 https://#:8080 进行身份验证,并且域为 master
,则使用 users
作为 ENDPOINT 将创建 https://#:8080/admin/realms/master/users 资源 URL。
如果您将 ENDPOINT 设置为 clients
,则有效的资源 URI 为 https://#:8080/admin/realms/master/clients。
Keycloak 具有 realms
端点,它是域的容器。它解析为
SERVER_URI/admin/realms
Keycloak 具有 serverinfo
端点。此端点独立于域。
当您以具有 realm-admin 权限的用户身份进行身份验证时,您可能需要在多个域上执行命令。如果是这样,请指定 -r
选项以告知 CLI 要显式针对哪个域执行命令。命令将使用 TARGET_REALM
,而不是使用 kcadm.sh config credentials
的 --realm
选项指定的 REALM
。
SERVER_URI/admin/realms/TARGET_REALM/ENDPOINT
例如
$ kcadm.sh config credentials --server https://#:8080 --realm master --user admin $ kcadm.sh create users -s username=testuser -s enabled=true -r demorealm
在此示例中,您启动一个会话,以 master
域中的 admin
用户身份进行身份验证。然后,您对资源 URL https://#:8080/admin/realms/demorealm/users
执行 POST 调用。
create
和 update
命令将 JSON 正文发送到服务器。您可以使用 -f FILENAME
从文件中读取预先制作的文档。当您可以使用 -f -
选项时,Keycloak 会从标准输入中读取消息正文。您可以指定单个属性及其值,如 create users
示例中所示。Keycloak 将属性组合成 JSON 正文并将其发送到服务器。
在 name=value 对中使用的值(在 --set、-s 选项中使用)被假定为 JSON。如果无法解析为有效的 JSON,则会将其作为文本值发送到服务器。 如果值在 shell 处理后用引号括起来,但不是有效的 JSON,则引号将被剥离,并且值的其余部分将作为文本发送。此行为已弃用,请考虑不带引号指定您的值,或使用双引号指定有效的 JSON 字符串文字。 |
Keycloak 中有几种方法可用于使用 update
命令更新资源。您可以确定资源的当前状态并将其保存到文件中,编辑该文件,然后将其发送到服务器进行更新。
例如
$ kcadm.sh get realms/demorealm > demorealm.json $ vi demorealm.json $ kcadm.sh update realms/demorealm -f demorealm.json
此方法使用发送的 JSON 文档中的属性更新服务器上的资源。
另一种方法是通过使用 -s, --set
选项设置新值来执行即时更新。
例如
$ kcadm.sh update realms/demorealm -s enabled=false
此方法将 enabled
属性设置为 false
。
默认情况下,update
命令执行 get
,然后将新属性值与现有值合并。在某些情况下,端点可能支持 put
命令,但不支持 get
命令。您可以使用 -n
选项执行无合并更新,这将执行 put
命令,而无需首先运行 get
命令。
域操作
创建新域
在 realms
端点上使用 create
命令来创建新的已启用域。将属性设置为 realm
和 enabled
。
$ kcadm.sh create realms -s realm=demorealm -s enabled=true
Keycloak 默认禁用域。您可以通过启用域立即将其用于身份验证。
新对象的描述也可以是 JSON 格式。
$ kcadm.sh create realms -f demorealm.json
您可以直接从文件发送包含域属性的 JSON 文档,或将文档通过管道传递到标准输入。
例如
-
Linux
$ kcadm.sh create realms -f - << EOF { "realm": "demorealm", "enabled": true } EOF
-
Windows
c:\> echo { "realm": "demorealm", "enabled": true } | kcadm create realms -f -
列出现有域
此命令返回所有域的列表。
$ kcadm.sh get realms
Keycloak 在服务器上过滤域列表,以仅返回用户可以看到的域。 |
所有域属性的列表可能很冗长,并且大多数用户只对属性的子集感兴趣,例如域名和域的启用状态。您可以使用 --fields
选项指定要返回的属性。
$ kcadm.sh get realms --fields realm,enabled
您可以将结果显示为逗号分隔值。
$ kcadm.sh get realms --fields realm --format csv --noquotes
获取特定域
将域名附加到集合 URI 以获取单个域。
$ kcadm.sh get realms/master
更新域
-
当您不想更改所有域的属性时,请使用
-s
选项为属性设置新值。例如
$ kcadm.sh update realms/demorealm -s enabled=false
-
如果您想将所有可写属性设置为新值
-
运行
get
命令。 -
编辑 JSON 文件中的当前值。
-
重新提交。
例如
$ kcadm.sh get realms/demorealm > demorealm.json $ vi demorealm.json $ kcadm.sh update realms/demorealm -f demorealm.json
-
删除域
运行以下命令以删除域
$ kcadm.sh delete realms/demorealm
为域启用所有登录页面选项
将控制特定功能的属性设置为 true
。
例如
$ kcadm.sh update realms/demorealm -s registrationAllowed=true -s registrationEmailAsUsername=true -s rememberMe=true -s verifyEmail=true -s resetPasswordAllowed=true -s editUsernameAllowed=true
列出域密钥
对目标域的 keys
端点使用 get
操作。
$ kcadm.sh get keys -r demorealm
生成新域密钥
-
在添加新的 RSA 生成的密钥对之前,获取目标域的 ID。
例如
$ kcadm.sh get realms/demorealm --fields id --format csv --noquotes
-
添加一个新的密钥提供程序,其优先级高于现有提供程序,如
kcadm.sh get keys -r demorealm
所示。例如
-
Linux
$ kcadm.sh create components -r demorealm -s name=rsa-generated -s providerId=rsa-generated -s providerType=org.keycloak.keys.KeyProvider -s parentId=959844c1-d149-41d7-8359-6aa527fca0b0 -s 'config.priority=["101"]' -s 'config.enabled=["true"]' -s 'config.active=["true"]' -s 'config.keySize=["2048"]'
-
Windows
c:\> kcadm create components -r demorealm -s name=rsa-generated -s providerId=rsa-generated -s providerType=org.keycloak.keys.KeyProvider -s parentId=959844c1-d149-41d7-8359-6aa527fca0b0 -s "config.priority=[\"101\"]" -s "config.enabled=[\"true\"]" -s "config.active=[\"true\"]" -s "config.keySize=[\"2048\"]"
-
-
将
parentId
属性设置为目标域 ID 的值。新添加的密钥现在是活动密钥,如
kcadm.sh get keys -r demorealm
所示。
从 Java 密钥库文件添加新域密钥
-
添加一个新的密钥提供程序,以添加预先准备为 JKS 文件的新密钥对。
例如,在
-
Linux
$ kcadm.sh create components -r demorealm -s name=java-keystore -s providerId=java-keystore -s providerType=org.keycloak.keys.KeyProvider -s parentId=959844c1-d149-41d7-8359-6aa527fca0b0 -s 'config.priority=["101"]' -s 'config.enabled=["true"]' -s 'config.active=["true"]' -s 'config.keystore=["/opt/keycloak/keystore.jks"]' -s 'config.keystorePassword=["secret"]' -s 'config.keyPassword=["secret"]' -s 'config.keyAlias=["localhost"]'
-
Windows
c:\> kcadm create components -r demorealm -s name=java-keystore -s providerId=java-keystore -s providerType=org.keycloak.keys.KeyProvider -s parentId=959844c1-d149-41d7-8359-6aa527fca0b0 -s "config.priority=[\"101\"]" -s "config.enabled=[\"true\"]" -s "config.active=[\"true\"]" -s "config.keystore=[\"/opt/keycloak/keystore.jks\"]" -s "config.keystorePassword=[\"secret\"]" -s "config.keyPassword=[\"secret\"]" -s "config.keyAlias=[\"localhost\"]"
-
-
确保您更改
keystore
、keystorePassword
、keyPassword
和alias
的属性值,以匹配您的特定密钥库。 -
将
parentId
属性设置为目标域 ID 的值。
使密钥被动或禁用密钥
-
确定您要使其被动的密钥。
$ kcadm.sh get keys -r demorealm
-
使用密钥的
providerId
属性构造端点 URI,例如components/PROVIDER_ID
。 -
执行
update
。例如
-
Linux
$ kcadm.sh update components/PROVIDER_ID -r demorealm -s 'config.active=["false"]'
-
Windows
c:\> kcadm update components/PROVIDER_ID -r demorealm -s "config.active=[\"false\"]"
您可以更新其他密钥属性
-
设置新的
enabled
值以禁用密钥,例如,config.enabled=["false"]
。 -
设置新的
priority
值以更改密钥的优先级,例如,config.priority=["110"]
。
-
删除旧密钥
-
确保您要删除的密钥处于非活动状态并且您已禁用它。此操作是为了防止应用程序和用户持有的现有令牌失败。
-
确定要删除的密钥。
$ kcadm.sh get keys -r demorealm
-
使用密钥的
providerId
执行删除。$ kcadm.sh delete components/PROVIDER_ID -r demorealm
配置域的事件日志记录
对 events/config
端点使用 update
命令。
eventsListeners
属性包含 EventListenerProviderFactory ID 的列表,指定接收事件的所有事件侦听器。属性可用于控制内置事件存储,因此您可以使用 Admin REST API 查询过去的事件。Keycloak 对服务调用的日志记录 (eventsEnabled
) 和由 Admin Console 或 Admin REST API 触发的审计事件 (adminEventsEnabled
) 具有单独的控制。您可以设置 eventsExpiration
事件过期,以防止数据库被填满。Keycloak 将 eventsExpiration
设置为以秒为单位的生存时间。
您可以设置一个内置事件侦听器,该侦听器接收所有事件并通过 JBoss-logging 记录事件。使用 org.keycloak.events
记录器,Keycloak 将错误事件记录为 WARN
,并将其他事件记录为 DEBUG
。
例如
-
Linux
$ kcadm.sh update events/config -r demorealm -s 'eventsListeners=["jboss-logging"]'
-
Windows
c:\> kcadm update events/config -r demorealm -s "eventsListeners=[\"jboss-logging\"]"
例如
您可以为所有可用的 ERROR 事件(不包括审计事件)开启两天的存储,以便您可以通过 Admin REST 检索事件。
-
Linux
$ kcadm.sh update events/config -r demorealm -s eventsEnabled=true -s 'enabledEventTypes=["LOGIN_ERROR","REGISTER_ERROR","LOGOUT_ERROR","CODE_TO_TOKEN_ERROR","CLIENT_LOGIN_ERROR","FEDERATED_IDENTITY_LINK_ERROR","REMOVE_FEDERATED_IDENTITY_ERROR","UPDATE_EMAIL_ERROR","UPDATE_PROFILE_ERROR","UPDATE_PASSWORD_ERROR","UPDATE_TOTP_ERROR","UPDATE_CREDENTIAL_ERROR","VERIFY_EMAIL_ERROR","REMOVE_TOTP_ERROR","REMOVE_CREDENTIAL_ERROR","SEND_VERIFY_EMAIL_ERROR","SEND_RESET_PASSWORD_ERROR","SEND_IDENTITY_PROVIDER_LINK_ERROR","RESET_PASSWORD_ERROR","IDENTITY_PROVIDER_FIRST_LOGIN_ERROR","IDENTITY_PROVIDER_POST_LOGIN_ERROR","CUSTOM_REQUIRED_ACTION_ERROR","EXECUTE_ACTIONS_ERROR","CLIENT_REGISTER_ERROR","CLIENT_UPDATE_ERROR","CLIENT_DELETE_ERROR"]' -s eventsExpiration=172800
-
Windows
c:\> kcadm update events/config -r demorealm -s eventsEnabled=true -s "enabledEventTypes=[\"LOGIN_ERROR\",\"REGISTER_ERROR\",\"LOGOUT_ERROR\",\"CODE_TO_TOKEN_ERROR\",\"CLIENT_LOGIN_ERROR\",\"FEDERATED_IDENTITY_LINK_ERROR\",\"REMOVE_FEDERATED_IDENTITY_ERROR\",\"UPDATE_EMAIL_ERROR\",\"UPDATE_PROFILE_ERROR\",\"UPDATE_PASSWORD_ERROR\",\"UPDATE_TOTP_ERROR\",\"UPDATE_CREDENTIAL_ERROR\",\"VERIFY_EMAIL_ERROR\",\"REMOVE_TOTP_ERROR\",\"REMOVE_CREDENTIAL_ERROR\",\"SEND_VERIFY_EMAIL_ERROR\",\"SEND_RESET_PASSWORD_ERROR\",\"SEND_IDENTITY_PROVIDER_LINK_ERROR\",\"RESET_PASSWORD_ERROR\",\"IDENTITY_PROVIDER_FIRST_LOGIN_ERROR\",\"IDENTITY_PROVIDER_POST_LOGIN_ERROR\",\"CUSTOM_REQUIRED_ACTION_ERROR\",\"EXECUTE_ACTIONS_ERROR\",\"CLIENT_REGISTER_ERROR\",\"CLIENT_UPDATE_ERROR\",\"CLIENT_DELETE_ERROR\"]" -s eventsExpiration=172800
您可以将存储的事件类型重置为所有可用的事件类型。将值设置为空列表与枚举所有类型相同。
$ kcadm.sh update events/config -r demorealm -s enabledEventTypes=[]
您可以启用审计事件的存储。
$ kcadm.sh update events/config -r demorealm -s adminEventsEnabled=true -s adminEventsDetailsEnabled=true
您可以获取最近 100 个事件。事件从最新到最旧排序。
$ kcadm.sh get events --offset 0 --limit 100
您可以删除所有已保存的事件。
$ kcadm delete events
刷新缓存
-
使用
create
命令和以下端点之一来清除缓存-
clear-realm-cache
-
clear-user-cache
-
clear-keys-cache
-
-
将
realm
设置为与目标域相同的值。例如
$ kcadm.sh create clear-realm-cache -r demorealm -s realm=demorealm $ kcadm.sh create clear-user-cache -r demorealm -s realm=demorealm $ kcadm.sh create clear-keys-cache -r demorealm -s realm=demorealm
从导出的 .json 文件导入域
-
对
partialImport
端点使用create
命令。 -
将
ifResourceExists
设置为FAIL
、SKIP
或OVERWRITE
。 -
使用
-f
提交导出的域.json
文件。例如
$ kcadm.sh create partialImport -r demorealm2 -s ifResourceExists=FAIL -o -f demorealm.json
如果域尚不存在,请先创建它。
例如
$ kcadm.sh create realms -s realm=demorealm2 -s enabled=true
角色操作
创建域角色
使用 roles
端点创建域角色。
$ kcadm.sh create roles -r demorealm -s name=user -s 'description=Regular user with a limited set of permissions'
创建客户端角色
-
确定客户端。
-
使用
get
命令列出可用的客户端。$ kcadm.sh get clients -r demorealm --fields id,clientId
-
通过使用
clientId
属性构造端点 URI 来创建新角色,例如clients/ID/roles
。例如
$ kcadm.sh create clients/a95b6af3-0bdc-4878-ae2e-6d61a4eca9a0/roles -r demorealm -s name=editor -s 'description=Editor can edit, and publish any article'
列出域角色
对 roles
端点使用 get
命令以列出现有的域角色。
$ kcadm.sh get roles -r demorealm
您也可以使用 get-roles
命令。
$ kcadm.sh get-roles -r demorealm
列出客户端角色
Keycloak 具有专用的 get-roles
命令,以简化域角色和客户端角色的列表。该命令是 get
命令的扩展,其行为与 get
命令相同,但具有列出角色的附加语义。
使用 get-roles
命令,方法是传递 clientId (--cclientid
) 选项或 id
(--cid
) 选项来标识要列出客户端角色的客户端。
例如
$ kcadm.sh get-roles -r demorealm --cclientid realm-management
获取特定域角色
使用 get
命令和角色 name
来构造特定域角色的端点 URI,roles/ROLE_NAME
,其中 user
是现有角色的名称。
例如
$ kcadm.sh get roles/user -r demorealm
您可以使用 get-roles
命令,方法是传递角色名称 (--rolename
选项) 或 ID (--roleid
选项)。
例如
$ kcadm.sh get-roles -r demorealm --rolename user
获取特定客户端角色
使用 get-roles
命令,方法是传递 clientId 属性 (--cclientid
选项) 或 ID 属性 (--cid
选项) 以标识客户端,并传递角色名称 (--rolename
选项) 或角色 ID 属性 (--roleid
) 以标识特定的客户端角色。
例如
$ kcadm.sh get-roles -r demorealm --cclientid realm-management --rolename manage-clients
更新域角色
将 update
命令与您用于获取特定域角色的端点 URI 一起使用。
例如
$ kcadm.sh update roles/user -r demorealm -s 'description=Role representing a regular user'
更新客户端角色
将 update
命令与您用于获取特定客户端角色的端点 URI 一起使用。
例如
$ kcadm.sh update clients/a95b6af3-0bdc-4878-ae2e-6d61a4eca9a0/roles/editor -r demorealm -s 'description=User that can edit, and publish articles'
删除域角色
将 delete
命令与您用于获取特定域角色的端点 URI 一起使用。
例如
$ kcadm.sh delete roles/user -r demorealm
删除客户端角色
将 delete
命令与您用于获取特定客户端角色的端点 URI 一起使用。
例如
$ kcadm.sh delete clients/a95b6af3-0bdc-4878-ae2e-6d61a4eca9a0/roles/editor -r demorealm
列出复合角色的已分配、可用和有效域角色
使用 get-roles
命令列出组合角色的已分配、可用和有效域角色。
-
要列出组合角色的已分配域角色,请通过名称 (
--rname
选项) 或 ID (--rid
选项) 指定目标组合角色。例如
$ kcadm.sh get-roles -r demorealm --rname testrole
-
使用
--effective
选项列出有效域角色。例如
$ kcadm.sh get-roles -r demorealm --rname testrole --effective
-
使用
--available
选项列出可以添加到组合角色中的域角色。例如
$ kcadm.sh get-roles -r demorealm --rname testrole --available
列出组合角色的已分配、可用和有效客户端角色
使用 get-roles
命令列出组合角色的已分配、可用和有效客户端角色。
-
要列出组合角色的已分配客户端角色,您可以通过名称 (
--rname
选项) 或 ID (--rid
选项) 指定目标组合角色,并通过 clientId 属性 (--cclientid
选项) 或 ID (--cid
选项) 指定客户端。例如
$ kcadm.sh get-roles -r demorealm --rname testrole --cclientid realm-management
-
使用
--effective
选项列出有效域角色。例如
$ kcadm.sh get-roles -r demorealm --rname testrole --cclientid realm-management --effective
-
使用
--available
选项列出可以添加到目标组合角色中的域角色。例如
$ kcadm.sh get-roles -r demorealm --rname testrole --cclientid realm-management --available
向组合角色添加域角色
Keycloak 提供了 add-roles
命令,用于添加域角色和客户端角色。
此示例将 user
角色添加到组合角色 testrole
。
$ kcadm.sh add-roles --rname testrole --rolename user -r demorealm
从组合角色中移除域角色
Keycloak 提供了 remove-roles
命令,用于移除域角色和客户端角色。
以下示例从目标组合角色 testrole
中移除 user
角色。
$ kcadm.sh remove-roles --rname testrole --rolename user -r demorealm
向域角色添加客户端角色
Keycloak 提供了 add-roles
命令,用于添加域角色和客户端角色。
以下示例将客户端 realm-management
上定义的角色 create-client
和 view-users
添加到 testrole
组合角色。
$ kcadm.sh add-roles -r demorealm --rname testrole --cclientid realm-management --rolename create-client --rolename view-users
向客户端角色添加客户端角色
-
通过使用
get-roles
命令确定组合客户端角色的 ID。例如
$ kcadm.sh get-roles -r demorealm --cclientid test-client --rolename operations
-
假设存在一个客户端,其 clientId 属性名为
test-client
,客户端角色名为support
,客户端角色名为operations
,后者成为 ID 为 "fc400897-ef6a-4e8c-872b-1581b7fa8a71" 的组合角色。 -
使用以下示例向组合角色添加另一个角色。
$ kcadm.sh add-roles -r demorealm --cclientid test-client --rid fc400897-ef6a-4e8c-872b-1581b7fa8a71 --rolename support
-
使用
get-roles --all
命令列出组合角色的角色。例如
$ kcadm.sh get-roles --rid fc400897-ef6a-4e8c-872b-1581b7fa8a71 --all
从组合角色中移除客户端角色
使用 remove-roles
命令从组合角色中移除客户端角色。
使用以下示例从组合角色 testrole
中移除客户端 realm-management
上定义的两个角色,即 create-client
角色和 view-users
角色。
$ kcadm.sh remove-roles -r demorealm --rname testrole --cclientid realm-management --rolename create-client --rolename view-users
向组添加客户端角色
使用 add-roles
命令添加域角色和客户端角色。
以下示例将客户端 realm-management
上定义的角色 create-client
和 view-users
添加到 Group
组 (--gname
选项)。或者,您可以通过 ID (--gid
选项) 指定组。
有关更多信息,请参阅 组操作。
$ kcadm.sh add-roles -r demorealm --gname Group --cclientid realm-management --rolename create-client --rolename view-users
从组中移除客户端角色
使用 remove-roles
命令从组中移除客户端角色。
以下示例从 Group
组中移除客户端 realm-management
上定义的两个角色,即 create-client
和 view-users
。
有关更多信息,请参阅 组操作。
$ kcadm.sh remove-roles -r demorealm --gname Group --cclientid realm-management --rolename create-client --rolename view-users
客户端操作
创建客户端
-
在
clients
端点上运行create
命令以创建新客户端。例如
$ kcadm.sh create clients -r demorealm -s clientId=myapp -s enabled=true
-
如果需要为适配器设置用于身份验证的密钥,请指定密钥。
例如
$ kcadm.sh create clients -r demorealm -s clientId=myapp -s enabled=true -s clientAuthenticatorType=client-secret -s secret=d0b8122f-8dfb-46b7-b68a-f5cc4e25d000
列出客户端
使用 clients
端点上的 get
命令列出客户端。
此示例过滤输出,仅列出 id
和 clientId
属性
$ kcadm.sh get clients -r demorealm --fields id,clientId
获取特定客户端
使用客户端 ID 构建指向特定客户端的端点 URI,例如 clients/ID
。
例如
$ kcadm.sh get clients/c7b8547f-e748-4333-95d0-410b76b3f4a3 -r demorealm
获取特定客户端的当前密钥
使用客户端 ID 构建端点 URI,例如 clients/ID/client-secret
。
例如
$ kcadm.sh get clients/$CID/client-secret -r demorealm
为特定客户端生成新密钥
使用客户端 ID 构建端点 URI,例如 clients/ID/client-secret
。
例如
$ kcadm.sh create clients/$CID/client-secret -r demorealm
更新特定客户端的当前密钥
使用客户端 ID 构建端点 URI,例如 clients/ID
。
例如
$ kcadm.sh update clients/$CID -s "secret=newSecret" -r demorealm
获取特定客户端的适配器配置文件 (keycloak.json)
使用客户端 ID 构建指向特定客户端的端点 URI,例如 clients/ID/installation/providers/keycloak-oidc-keycloak-json
。
例如
$ kcadm.sh get clients/c7b8547f-e748-4333-95d0-410b76b3f4a3/installation/providers/keycloak-oidc-keycloak-json -r demorealm
获取特定客户端的 WildFly 子系统适配器配置
使用客户端 ID 构建指向特定客户端的端点 URI,例如 clients/ID/installation/providers/keycloak-oidc-jboss-subsystem
。
例如
$ kcadm.sh get clients/c7b8547f-e748-4333-95d0-410b76b3f4a3/installation/providers/keycloak-oidc-jboss-subsystem -r demorealm
获取特定客户端的 Docker-v2 示例配置
使用客户端 ID 构建指向特定客户端的端点 URI,例如 clients/ID/installation/providers/docker-v2-compose-yaml
。
响应为 .zip
格式。
例如
$ kcadm.sh get https://#:8080/admin/realms/demorealm/clients/8f271c35-44e3-446f-8953-b0893810ebe7/installation/providers/docker-v2-compose-yaml -r demorealm > keycloak-docker-compose-yaml.zip
更新客户端
使用 update
命令以及您用于获取特定客户端的相同端点 URI。
例如
-
Linux
$ kcadm.sh update clients/c7b8547f-e748-4333-95d0-410b76b3f4a3 -r demorealm -s enabled=false -s publicClient=true -s 'redirectUris=["https://#:8080/myapp/*"]' -s baseUrl=https://#:8080/myapp -s adminUrl=https://#:8080/myapp
-
Windows
c:\> kcadm update clients/c7b8547f-e748-4333-95d0-410b76b3f4a3 -r demorealm -s enabled=false -s publicClient=true -s "redirectUris=[\"https://#:8080/myapp/*\"]" -s baseUrl=https://#:8080/myapp -s adminUrl=https://#:8080/myapp
删除客户端
使用 delete
命令以及您用于获取特定客户端的相同端点 URI。
例如
$ kcadm.sh delete clients/c7b8547f-e748-4333-95d0-410b76b3f4a3 -r demorealm
为客户端的服务帐户添加或移除角色
客户端的服务帐户是一个用户帐户,用户名为 service-account-CLIENT_ID
。您可以对此帐户执行与常规帐户相同的用户操作。
用户操作
创建用户
在 users
端点上运行 create
命令以创建新用户。
例如
$ kcadm.sh create users -r demorealm -s username=testuser -s enabled=true
列出用户
使用 users
端点列出用户。目标用户下次登录时必须更改密码。
例如
$ kcadm.sh get users -r demorealm --offset 0 --limit 1000
您可以按 username
、firstName
、lastName
或 email
过滤用户。
例如
$ kcadm.sh get users -r demorealm -q q=email:google.com $ kcadm.sh get users -r demorealm -q q=username:testuser
过滤不使用精确匹配。此示例将 |
对于客户端、组和用户,您可以通过指定更复杂的 q
查询参数跨多个属性进行过滤。您可以像这样使用 -q q="field1:value1 field2:value2"。Keycloak 仅返回与所有属性的条件都匹配的用户。
获取特定用户
使用用户 ID 构建端点 URI,例如 users/USER_ID
。
例如
$ kcadm.sh get users/0ba7a3fd-6fd8-48cd-a60b-2e8fd82d56e2 -r demorealm
更新用户
使用 update
命令以及您用于获取特定用户的相同端点 URI。
例如
-
Linux
$ kcadm.sh update users/0ba7a3fd-6fd8-48cd-a60b-2e8fd82d56e2 -r demorealm -s 'requiredActions=["VERIFY_EMAIL","UPDATE_PROFILE","CONFIGURE_TOTP","UPDATE_PASSWORD"]'
-
Windows
c:\> kcadm update users/0ba7a3fd-6fd8-48cd-a60b-2e8fd82d56e2 -r demorealm -s "requiredActions=[\"VERIFY_EMAIL\",\"UPDATE_PROFILE\",\"CONFIGURE_TOTP\",\"UPDATE_PASSWORD\"]"
删除用户
使用 delete
命令以及您用于获取特定用户的相同端点 URI。
例如
$ kcadm.sh delete users/0ba7a3fd-6fd8-48cd-a60b-2e8fd82d56e2 -r demorealm
重置用户密码
使用专用的 set-password
命令重置用户密码。
例如
$ kcadm.sh set-password -r demorealm --username testuser --new-password NEWPASSWORD --temporary
此命令为用户设置临时密码。目标用户下次登录时必须更改密码。
您可以使用 --userid
通过使用 id
属性来指定用户。
您可以使用在从用于获取特定用户的端点构建的端点上使用 update
命令来实现相同的结果,例如 users/USER_ID/reset-password
。
例如
$ kcadm.sh update users/0ba7a3fd-6fd8-48cd-a60b-2e8fd82d56e2/reset-password -r demorealm -s type=password -s value=NEWPASSWORD -s temporary=true -n
-n
参数确保 Keycloak 执行 PUT
命令,而无需在 PUT
命令之前执行 GET
命令。这是必要的,因为 reset-password
端点不支持 GET
。
列出用户的已分配、可用和有效域角色
您可以使用 get-roles
命令列出用户的已分配、可用和有效域角色。
-
通过用户名或 ID 指定目标用户,以列出用户的已分配域角色。
例如
$ kcadm.sh get-roles -r demorealm --uusername testuser
-
使用
--effective
选项列出有效域角色。例如
$ kcadm.sh get-roles -r demorealm --uusername testuser --effective
-
使用
--available
选项列出可以添加到用户中的域角色。例如
$ kcadm.sh get-roles -r demorealm --uusername testuser --available
列出用户的已分配、可用和有效客户端角色
使用 get-roles
命令列出用户的已分配、可用和有效客户端角色。
-
通过用户名 (
--uusername
选项) 或 ID (--uid
选项) 指定目标用户,并通过 clientId 属性 (--cclientid
选项) 或 ID (--cid
选项) 指定客户端,以列出用户的已分配客户端角色。例如
$ kcadm.sh get-roles -r demorealm --uusername testuser --cclientid realm-management
-
使用
--effective
选项列出有效域角色。例如
$ kcadm.sh get-roles -r demorealm --uusername testuser --cclientid realm-management --effective
-
使用
--available
选项列出可以添加到用户中的域角色。例如
$ kcadm.sh get-roles -r demorealm --uusername testuser --cclientid realm-management --available
向用户添加域角色
使用 add-roles
命令向用户添加域角色。
使用以下示例将 user
角色添加到用户 testuser
$ kcadm.sh add-roles --uusername testuser --rolename user -r demorealm
从用户中移除域角色
使用 remove-roles
命令从用户中移除域角色。
使用以下示例从用户 testuser
中移除 user
角色
$ kcadm.sh remove-roles --uusername testuser --rolename user -r demorealm
向用户添加客户端角色
使用 add-roles
命令向用户添加客户端角色。
使用以下示例将客户端 realm-management
上定义的两个角色,即 create-client
角色和 view-users
角色,添加到用户 testuser
。
$ kcadm.sh add-roles -r demorealm --uusername testuser --cclientid realm-management --rolename create-client --rolename view-users
从用户中移除客户端角色
使用 remove-roles
命令从用户中移除客户端角色。
使用以下示例从 realm-management 客户端移除两个角色
$ kcadm.sh remove-roles -r demorealm --uusername testuser --cclientid realm-management --rolename create-client --rolename view-users
列出用户的会话
-
确定用户的 ID,
-
使用 ID 构建端点 URI,例如
users/ID/sessions
。 -
使用
get
命令检索用户会话的列表。例如
$ kcadm.sh get users/6da5ab89-3397-4205-afaa-e201ff638f9e/sessions -r demorealm
从特定会话中注销用户
-
如前所述,确定会话的 ID。
-
使用会话的 ID 构建端点 URI,例如
sessions/ID
。 -
使用
delete
命令使会话失效。例如
$ kcadm.sh delete sessions/d0eaa7cc-8c5d-489d-811a-69d3c4ec84d1 -r demorealm
从所有会话中注销用户
使用用户的 ID 构建端点 URI,例如 users/ID/logout
。
使用 create
命令对该端点 URI 执行 POST
。
例如
$ kcadm.sh create users/6da5ab89-3397-4205-afaa-e201ff638f9e/logout -r demorealm -s realm=demorealm -s user=6da5ab89-3397-4205-afaa-e201ff638f9e
组操作
创建组
在 groups
端点上使用 create
命令以创建新组。
例如
$ kcadm.sh create groups -r demorealm -s name=Group
列出组
在 groups
端点上使用 get
命令以列出组。
例如
$ kcadm.sh get groups -r demorealm
获取特定组
使用组的 ID 构建端点 URI,例如 groups/GROUP_ID
。
例如
$ kcadm.sh get groups/51204821-0580-46db-8f2d-27106c6b5ded -r demorealm
更新组
使用 update
命令以及您用于获取特定组的相同端点 URI。
例如
$ kcadm.sh update groups/51204821-0580-46db-8f2d-27106c6b5ded -s 'attributes.email=["group@example.com"]' -r demorealm
删除组
使用 delete
命令以及您用于获取特定组的相同端点 URI。
例如
$ kcadm.sh delete groups/51204821-0580-46db-8f2d-27106c6b5ded -r demorealm
创建子组
通过列出组查找父组的 ID。使用该 ID 构建端点 URI,例如 groups/GROUP_ID/children
。
例如
$ kcadm.sh create groups/51204821-0580-46db-8f2d-27106c6b5ded/children -r demorealm -s name=SubGroup
将组移动到另一个组下
-
查找现有父组的 ID 和现有子组的 ID。
-
使用父组的 ID 构建端点 URI,例如
groups/PARENT_GROUP_ID/children
。 -
在此端点上运行
create
命令,并将子组的 ID 作为 JSON 正文传递。
例如
$ kcadm.sh create groups/51204821-0580-46db-8f2d-27106c6b5ded/children -r demorealm -s id=08d410c6-d585-4059-bb07-54dcb92c5094 -s name=SubGroup
获取特定用户的组
使用用户的 ID 确定用户在组中的成员身份,以构建端点 URI,例如 users/USER_ID/groups
。
例如
$ kcadm.sh get users/b544f379-5fc4-49e5-8a8d-5cfb71f46f53/groups -r demorealm
将用户添加到组
使用 update
命令以及由用户 ID 和组 ID 组成的端点 URI,例如 users/USER_ID/groups/GROUP_ID
,将用户添加到组。
例如
$ kcadm.sh update users/b544f379-5fc4-49e5-8a8d-5cfb71f46f53/groups/ce01117a-7426-4670-a29a-5c118056fe20 -r demorealm -s realm=demorealm -s userId=b544f379-5fc4-49e5-8a8d-5cfb71f46f53 -s groupId=ce01117a-7426-4670-a29a-5c118056fe20 -n
从组中移除用户
在用于将用户添加到组的相同端点 URI 上使用 delete
命令,例如 users/USER_ID/groups/GROUP_ID
,以从组中移除用户。
例如
$ kcadm.sh delete users/b544f379-5fc4-49e5-8a8d-5cfb71f46f53/groups/ce01117a-7426-4670-a29a-5c118056fe20 -r demorealm
列出组的已分配、可用和有效域角色
使用专用的 get-roles
命令列出组的已分配、可用和有效域角色。
-
通过名称 (
--gname
选项)、路径 (--gpath
选项) 或 ID (--gid
选项) 指定目标组,以列出组的已分配域角色。例如
$ kcadm.sh get-roles -r demorealm --gname Group
-
使用
--effective
选项列出有效域角色。例如
$ kcadm.sh get-roles -r demorealm --gname Group --effective
-
使用
--available
选项列出可以添加到组中的域角色。例如
$ kcadm.sh get-roles -r demorealm --gname Group --available
列出组的已分配、可用和有效客户端角色
使用 get-roles
命令列出组的已分配、可用和有效客户端角色。
-
通过名称 (
--gname
选项) 或 ID (--gid
选项) 指定目标组, -
通过 clientId 属性 (
--cclientid
选项) 或 ID (--id
选项) 指定客户端,以列出用户的已分配客户端角色。例如
$ kcadm.sh get-roles -r demorealm --gname Group --cclientid realm-management
-
使用
--effective
选项列出有效域角色。例如
$ kcadm.sh get-roles -r demorealm --gname Group --cclientid realm-management --effective
-
使用
--available
选项列出您仍然可以添加到组中的域角色。例如
$ kcadm.sh get-roles -r demorealm --gname Group --cclientid realm-management --available
身份提供者操作
列出可用的身份提供者
使用 serverinfo
端点列出可用的身份提供者。
例如
$ kcadm.sh get serverinfo -r demorealm --fields 'identityProviders(*)'
Keycloak 处理 |
列出已配置的身份提供者
使用 identity-provider/instances
端点。
例如
$ kcadm.sh get identity-provider/instances -r demorealm --fields alias,providerId,enabled
获取特定的已配置身份提供者
使用身份提供者的 alias
属性构建端点 URI,例如 identity-provider/instances/ALIAS
,以获取特定的身份提供者。
例如
$ kcadm.sh get identity-provider/instances/facebook -r demorealm
移除特定的已配置身份提供者
使用 delete
命令以及您用于获取特定已配置身份提供者的相同端点 URI,以移除特定的已配置身份提供者。
例如
$ kcadm.sh delete identity-provider/instances/facebook -r demorealm
配置 Keycloak OpenID Connect 身份提供者
-
在创建新的身份提供者实例时,使用
keycloak-oidc
作为providerId
。 -
提供
config
属性:authorizationUrl
、tokenUrl
、clientId
和clientSecret
。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=keycloak-oidc -s providerId=keycloak-oidc -s enabled=true -s 'config.useJwksUrl="true"' -s config.authorizationUrl=https://#:8180/realms/demorealm/protocol/openid-connect/auth -s config.tokenUrl=https://#:8180/realms/demorealm/protocol/openid-connect/token -s config.clientId=demo-oidc-provider -s config.clientSecret=secret
配置 OpenID Connect 身份提供者
配置通用的 OpenID Connect 提供者的方式与配置 Keycloak OpenID Connect 提供者的方式相同,不同之处在于您将 providerId
属性值设置为 oidc
。
配置 SAML 2 身份提供者
-
使用
saml
作为providerId
。 -
提供
config
属性:singleSignOnServiceUrl
、nameIDPolicyFormat
和signatureAlgorithm
。
例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=saml -s providerId=saml -s enabled=true -s 'config.useJwksUrl="true"' -s config.singleSignOnServiceUrl=https://#:8180/realms/saml-broker-realm/protocol/saml -s config.nameIDPolicyFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent -s config.signatureAlgorithm=RSA_SHA256
配置 Facebook 身份提供者
-
使用
facebook
作为providerId
。 -
提供
config
属性:clientId
和clientSecret
。您可以在 Facebook 开发者应用程序配置页面中找到这些属性,用于您的应用程序。有关更多信息,请参阅 Facebook 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=facebook -s providerId=facebook -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=FACEBOOK_CLIENT_ID -s config.clientSecret=FACEBOOK_CLIENT_SECRET
配置 Google 身份提供者
-
使用
google
作为providerId
。 -
提供
config
属性:clientId
和clientSecret
。您可以在 Google 开发者应用程序配置页面中找到这些属性,用于您的应用程序。有关更多信息,请参阅 Google 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=google -s providerId=google -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=GOOGLE_CLIENT_ID -s config.clientSecret=GOOGLE_CLIENT_SECRET
配置 Twitter 身份提供者
-
使用
twitter
作为providerId
。 -
提供
config
属性clientId
和clientSecret
。您可以在 Twitter 应用程序管理应用程序配置页面中找到这些属性,用于您的应用程序。有关更多信息,请参阅 Twitter 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=google -s providerId=google -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=TWITTER_API_KEY -s config.clientSecret=TWITTER_API_SECRET
配置 GitHub 身份提供者
-
使用
github
作为providerId
。 -
提供
config
属性clientId
和clientSecret
。您可以在 GitHub 开发者应用程序设置页面中找到您应用程序的这些属性。有关更多信息,请参阅 GitHub 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=github -s providerId=github -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=GITHUB_CLIENT_ID -s config.clientSecret=GITHUB_CLIENT_SECRET
配置 LinkedIn 身份提供程序
-
使用
linkedin
作为providerId
。 -
提供
config
属性clientId
和clientSecret
。您可以在 LinkedIn 开发者控制台应用程序页面中找到您应用程序的这些属性。有关更多信息,请参阅 LinkedIn 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=linkedin -s providerId=linkedin -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=LINKEDIN_CLIENT_ID -s config.clientSecret=LINKEDIN_CLIENT_SECRET
配置 Microsoft Live 身份提供程序
-
使用
microsoft
作为providerId
。 -
提供
config
属性clientId
和clientSecret
。您可以在 Microsoft 应用程序注册门户页面中找到您应用程序的这些属性。有关更多信息,请参阅 Microsoft 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=microsoft -s providerId=microsoft -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=MICROSOFT_APP_ID -s config.clientSecret=MICROSOFT_PASSWORD
配置 Stack Overflow 身份提供程序
-
使用
stackoverflow
命令作为providerId
。 -
提供
config
属性clientId
、clientSecret
和key
。您可以在 Stack Apps OAuth 页面中找到您应用程序的这些属性。有关更多信息,请参阅 Stack Overflow 身份代理 页面。例如
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=stackoverflow -s providerId=stackoverflow -s enabled=true -s 'config.useJwksUrl="true"' -s config.clientId=STACKAPPS_CLIENT_ID -s config.clientSecret=STACKAPPS_CLIENT_SECRET -s config.key=STACKAPPS_KEY
存储提供程序操作
配置 Kerberos 存储提供程序
-
对
components
端点使用create
命令。 -
将域 ID 指定为
parentId
属性的值。 -
将
kerberos
指定为providerId
属性的值,并将org.keycloak.storage.UserStorageProvider
指定为providerType
属性的值。 -
例如
$ kcadm.sh create components -r demorealm -s parentId=demorealmId -s id=demokerberos -s name=demokerberos -s providerId=kerberos -s providerType=org.keycloak.storage.UserStorageProvider -s 'config.priority=["0"]' -s 'config.debug=["false"]' -s 'config.allowPasswordAuthentication=["true"]' -s 'config.editMode=["UNSYNCED"]' -s 'config.updateProfileFirstLogin=["true"]' -s 'config.allowKerberosAuthentication=["true"]' -s 'config.kerberosRealm=["KEYCLOAK.ORG"]' -s 'config.keyTab=["http.keytab"]' -s 'config.serverPrincipal=["HTTP/localhost@KEYCLOAK.ORG"]' -s 'config.cachePolicy=["DEFAULT"]'
配置 LDAP 用户存储提供程序
-
对
components
端点使用create
命令。 -
将
ldap
指定为providerId
属性的值,并将org.keycloak.storage.UserStorageProvider
指定为providerType
属性的值。 -
将域 ID 作为
parentId
属性的值提供。 -
使用以下示例创建 Kerberos 集成的 LDAP 提供程序。
$ kcadm.sh create components -r demorealm -s name=kerberos-ldap-provider -s providerId=ldap -s providerType=org.keycloak.storage.UserStorageProvider -s parentId=3d9c572b-8f33-483f-98a6-8bb421667867 -s 'config.priority=["1"]' -s 'config.fullSyncPeriod=["-1"]' -s 'config.changedSyncPeriod=["-1"]' -s 'config.cachePolicy=["DEFAULT"]' -s config.evictionDay=[] -s config.evictionHour=[] -s config.evictionMinute=[] -s config.maxLifespan=[] -s 'config.batchSizeForSync=["1000"]' -s 'config.editMode=["WRITABLE"]' -s 'config.syncRegistrations=["false"]' -s 'config.vendor=["other"]' -s 'config.usernameLDAPAttribute=["uid"]' -s 'config.rdnLDAPAttribute=["uid"]' -s 'config.uuidLDAPAttribute=["entryUUID"]' -s 'config.userObjectClasses=["inetOrgPerson, organizationalPerson"]' -s 'config.connectionUrl=["ldap://#:10389"]' -s 'config.usersDn=["ou=People,dc=keycloak,dc=org"]' -s 'config.authType=["simple"]' -s 'config.bindDn=["uid=admin,ou=system"]' -s 'config.bindCredential=["secret"]' -s 'config.searchScope=["1"]' -s 'config.useTruststoreSpi=["always"]' -s 'config.connectionPooling=["true"]' -s 'config.pagination=["true"]' -s 'config.allowKerberosAuthentication=["true"]' -s 'config.serverPrincipal=["HTTP/localhost@KEYCLOAK.ORG"]' -s 'config.keyTab=["http.keytab"]' -s 'config.kerberosRealm=["KEYCLOAK.ORG"]' -s 'config.debug=["true"]' -s 'config.useKerberosForPasswordAuthentication=["true"]'
移除用户存储提供程序实例
-
使用存储提供程序实例的
id
属性来组成端点 URI,例如components/ID
。 -
对此端点运行
delete
命令。例如
$ kcadm.sh delete components/3d9c572b-8f33-483f-98a6-8bb421667867 -r demorealm
触发特定用户存储提供程序的所有用户同步
-
使用存储提供程序的
id
属性来组成端点 URI,例如user-storage/ID_OF_USER_STORAGE_INSTANCE/sync
。 -
添加
action=triggerFullSync
查询参数。 -
运行
create
命令。例如
$ kcadm.sh create user-storage/b7c63d02-b62a-4fc1-977c-947d6a09e1ea/sync?action=triggerFullSync
触发特定用户存储提供程序的已更改用户同步
-
使用存储提供程序的
id
属性来组成端点 URI,例如user-storage/ID_OF_USER_STORAGE_INSTANCE/sync
。 -
添加
action=triggerChangedUsersSync
查询参数。 -
运行
create
命令。例如
$ kcadm.sh create user-storage/b7c63d02-b62a-4fc1-977c-947d6a09e1ea/sync?action=triggerChangedUsersSync
测试 LDAP 用户存储连接性
-
在
testLDAPConnection
端点上运行get
命令。 -
提供查询参数
bindCredential
、bindDn
、connectionUrl
和useTruststoreSpi
。 -
将
action
查询参数设置为testConnection
。例如
$ kcadm.sh create testLDAPConnection -s action=testConnection -s bindCredential=secret -s bindDn=uid=admin,ou=system -s connectionUrl=ldap://#:10389 -s useTruststoreSpi=always
测试 LDAP 用户存储身份验证
-
在
testLDAPConnection
端点上运行get
命令。 -
提供查询参数
bindCredential
、bindDn
、connectionUrl
和useTruststoreSpi
。 -
将
action
查询参数设置为testAuthentication
。例如
$ kcadm.sh create testLDAPConnection -s action=testAuthentication -s bindCredential=secret -s bindDn=uid=admin,ou=system -s connectionUrl=ldap://#:10389 -s useTruststoreSpi=always
添加映射器
添加硬编码角色 LDAP 映射器
-
在
components
端点上运行create
命令。 -
将
providerType
属性设置为org.keycloak.storage.ldap.mappers.LDAPStorageMapper
。 -
将
parentId
属性设置为 LDAP 提供程序实例的 ID。 -
将
providerId
属性设置为hardcoded-ldap-role-mapper
。确保您提供role
配置参数的值。例如
$ kcadm.sh create components -r demorealm -s name=hardcoded-ldap-role-mapper -s providerId=hardcoded-ldap-role-mapper -s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper -s parentId=b7c63d02-b62a-4fc1-977c-947d6a09e1ea -s 'config.role=["realm-management.create-client"]'
添加 MS 活动目录 映射器
-
在
components
端点上运行create
命令。 -
将
providerType
属性设置为org.keycloak.storage.ldap.mappers.LDAPStorageMapper
。 -
将
parentId
属性设置为 LDAP 提供程序实例的 ID。 -
将
providerId
属性设置为msad-user-account-control-mapper
。例如
$ kcadm.sh create components -r demorealm -s name=msad-user-account-control-mapper -s providerId=msad-user-account-control-mapper -s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper -s parentId=b7c63d02-b62a-4fc1-977c-947d6a09e1ea
添加用户属性 LDAP 映射器
-
在
components
端点上运行create
命令。 -
将
providerType
属性设置为org.keycloak.storage.ldap.mappers.LDAPStorageMapper
。 -
将
parentId
属性设置为 LDAP 提供程序实例的 ID。 -
将
providerId
属性设置为user-attribute-ldap-mapper
。例如
$ kcadm.sh create components -r demorealm -s name=user-attribute-ldap-mapper -s providerId=user-attribute-ldap-mapper -s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper -s parentId=b7c63d02-b62a-4fc1-977c-947d6a09e1ea -s 'config."user.model.attribute"=["email"]' -s 'config."ldap.attribute"=["mail"]' -s 'config."read.only"=["false"]' -s 'config."always.read.value.from.ldap"=["false"]' -s 'config."is.mandatory.in.ldap"=["false"]'
添加组 LDAP 映射器
-
在
components
端点上运行create
命令。 -
将
providerType
属性设置为org.keycloak.storage.ldap.mappers.LDAPStorageMapper
。 -
将
parentId
属性设置为 LDAP 提供程序实例的 ID。 -
将
providerId
属性设置为group-ldap-mapper
。例如
$ kcadm.sh create components -r demorealm -s name=group-ldap-mapper -s providerId=group-ldap-mapper -s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper -s parentId=b7c63d02-b62a-4fc1-977c-947d6a09e1ea -s 'config."groups.dn"=[]' -s 'config."group.name.ldap.attribute"=["cn"]' -s 'config."group.object.classes"=["groupOfNames"]' -s 'config."preserve.group.inheritance"=["true"]' -s 'config."membership.ldap.attribute"=["member"]' -s 'config."membership.attribute.type"=["DN"]' -s 'config."groups.ldap.filter"=[]' -s 'config.mode=["LDAP_ONLY"]' -s 'config."user.roles.retrieve.strategy"=["LOAD_GROUPS_BY_MEMBER_ATTRIBUTE"]' -s 'config."mapped.group.attributes"=["admins-group"]' -s 'config."drop.non.existing.groups.during.sync"=["false"]' -s 'config.roles=["admins"]' -s 'config.groups=["admins-group"]' -s 'config.group=[]' -s 'config.preserve=["true"]' -s 'config.membership=["member"]'
添加全名 LDAP 映射器
-
在
components
端点上运行create
命令。 -
将
providerType
属性设置为org.keycloak.storage.ldap.mappers.LDAPStorageMapper
。 -
将
parentId
属性设置为 LDAP 提供程序实例的 ID。 -
将
providerId
属性设置为full-name-ldap-mapper
。例如
$ kcadm.sh create components -r demorealm -s name=full-name-ldap-mapper -s providerId=full-name-ldap-mapper -s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper -s parentId=b7c63d02-b62a-4fc1-977c-947d6a09e1ea -s 'config."ldap.full.name.attribute"=["cn"]' -s 'config."read.only"=["false"]' -s 'config."write.only"=["true"]'
身份验证操作
设置密码策略
-
将域的
passwordPolicy
属性设置为一个枚举表达式,该表达式包含特定的策略提供程序 ID 和可选配置。 -
使用以下示例将密码策略设置为默认值。默认值包括
-
210,000 次哈希迭代
-
至少一个特殊字符
-
至少一个大写字符
-
至少一个数字字符
-
不得等于用户的
username
-
至少八个字符长
$ kcadm.sh update realms/demorealm -s 'passwordPolicy="hashIterations and specialChars and upperCase and digits and notUsername and length"'
-
-
要使用与默认值不同的值,请在括号中传递配置。
-
使用以下示例将密码策略设置为
-
300,000 次哈希迭代
-
至少两个特殊字符
-
至少两个大写字符
-
至少两个小写字符
-
至少两个数字
-
至少九个字符长
-
不得等于用户的
username
-
至少四个更改后不重复
$ kcadm.sh update realms/demorealm -s 'passwordPolicy="hashIterations(300000) and specialChars(2) and upperCase(2) and lowerCase(2) and digits(2) and length(9) and notUsername and passwordHistory(4)"'
-
获取当前密码策略
您可以通过过滤除 passwordPolicy
属性之外的所有输出来获取当前域配置。
例如,显示 demorealm
的 passwordPolicy
。
$ kcadm.sh get realms/demorealm --fields passwordPolicy
列出身份验证流程
在 authentication/flows
端点上运行 get
命令。
例如
$ kcadm.sh get authentication/flows -r demorealm
获取特定的身份验证流程
在 authentication/flows/FLOW_ID
端点上运行 get
命令。
例如
$ kcadm.sh get authentication/flows/febfd772-e1a1-42fb-b8ae-00c0566fafb8 -r demorealm
列出流程的执行
在 authentication/flows/FLOW_ALIAS/executions
端点上运行 get
命令。
例如
$ kcadm.sh get authentication/flows/Copy%20of%20browser/executions -r demorealm
向执行添加配置
-
获取流程的执行。
-
记下流程的 ID。
-
在
authentication/executions/{executionId}/config
端点上运行create
命令。
例如
$ kcadm.sh create "authentication/executions/a3147129-c402-4760-86d9-3f2345e401c7/config" -r demorealm -b '{"config":{"x509-cert-auth.mapping-source-selection":"Match SubjectDN using regular expression","x509-cert-auth.regular-expression":"(.*?)(?:$)","x509-cert-auth.mapper-selection":"Custom Attribute Mapper","x509-cert-auth.mapper-selection.user-attribute-name":"usercertificate","x509-cert-auth.crl-checking-enabled":"","x509-cert-auth.crldp-checking-enabled":false,"x509-cert-auth.crl-relative-path":"crl.pem","x509-cert-auth.ocsp-checking-enabled":"","x509-cert-auth.ocsp-responder-uri":"","x509-cert-auth.keyusage":"","x509-cert-auth.extendedkeyusage":"","x509-cert-auth.confirmation-page-disallowed":""},"alias":"my_otp_config"}'
获取执行的配置
-
获取流程的执行。
-
记下其
authenticationConfig
属性,其中包含配置 ID。 -
在
authentication/config/ID
端点上运行get
命令。
例如
$ kcadm get "authentication/config/dd91611a-d25c-421a-87e2-227c18421833" -r demorealm
更新执行的配置
-
获取流程的执行。
-
获取流程的
authenticationConfig
属性。 -
从属性中记下配置 ID。
-
在
authentication/config/ID
端点上运行update
命令。
例如
$ kcadm update "authentication/config/dd91611a-d25c-421a-87e2-227c18421833" -r demorealm -b '{"id":"dd91611a-d25c-421a-87e2-227c18421833","alias":"my_otp_config","config":{"x509-cert-auth.extendedkeyusage":"","x509-cert-auth.mapper-selection.user-attribute-name":"usercertificate","x509-cert-auth.ocsp-responder-uri":"","x509-cert-auth.regular-expression":"(.*?)(?:$)","x509-cert-auth.crl-checking-enabled":"true","x509-cert-auth.confirmation-page-disallowed":"","x509-cert-auth.keyusage":"","x509-cert-auth.mapper-selection":"Custom Attribute Mapper","x509-cert-auth.crl-relative-path":"crl.pem","x509-cert-auth.crldp-checking-enabled":"false","x509-cert-auth.mapping-source-selection":"Match SubjectDN using regular expression","x509-cert-auth.ocsp-checking-enabled":""}}'
删除执行的配置
-
获取流程的执行。
-
获取流程的
authenticationConfig
属性。 -
从属性中记下配置 ID。
-
在
authentication/config/ID
端点上运行delete
命令。
例如
$ kcadm delete "authentication/config/dd91611a-d25c-421a-87e2-227c18421833" -r demorealm