8.3. 身份验证流
身份验证流程 是在登录、注册和其他红帽构建的 Keycloak 工作流期间进行身份验证、屏幕和操作的容器。
8.3.1. 内置流 复制链接链接已复制到粘贴板!
Red Hat build of Keycloak 有几个内置流。您无法修改这些流,但您可以更改流的要求以满足您的需要。
流程
- 点菜单中的 Authentication。
- 点列表中的 Browser 项查看详情。
浏览器流
8.3.1.1. auth 类型 复制链接链接已复制到粘贴板!
身份验证的名称或要执行的操作。如果身份验证缩进,它位于子流中。根据父进程的行为,它可能无法执行。
cookie
当用户第一次登录时,Red Hat build of Keycloak 会设置会话 Cookie。如果已经设置了 Cookie,则此身份验证类型成功。由于 Cookie 供应商返回成功,且在这个级别流的每个执行都是 替代的,因此红帽构建的 Keycloak 并不执行任何其他执行。这会导致成功登录。
Kerberos
这个验证器默认是禁用的,并在浏览器流中跳过。
身份提供程序 Redirector
此操作通过 Actions > Config 链接进行配置。它重定向到另一个 IdP 用于 身份代理。
表单
由于此子流标记为 替代,因此如果 Cookie 身份验证类型通过,则不会执行它。此子流包含需要执行的额外身份验证类型。Red Hat build of Keycloak 加载此子流的执行并处理它们。
第一次执行是 Username Password Form,它是一个呈现用户名和密码页面的身份验证类型。它标记为 必需,因此用户必须输入有效的用户名和密码。
第二个执行是 Browser - Conditional 2FA 子流。这个子流是 有条件的,并根据 Condition - User Configured 和 Condition - 凭证 执行的结果执行。如果结果为 true,Red Hat build of Keycloak 会加载这个子流的执行并处理它们。
下一个执行是 Condition - User Configured authentication。此身份验证会检查红帽构建的 Keycloak 是否在用户流中配置了其他执行。Browser - 只有用户配置了 OTP 凭证时,才会执行条件 2FA 子流。
下一个执行是 Condition - 凭证 身份验证。步骤检查身份验证过程是否已通过免密码 WebAuthn 凭证(passkey)验证用户身份,避免了 2FA。
最后执行是 OTP Form。Red Hat build of Keycloak 将这个执行标记为 替代,但只有用户因为 条件 子流中的设置而有 OTP 凭证时运行。如果没有设置 OTP 凭证,用户就不会看到 OTP 表单。
默认 浏览器 流在 Browser - Conditional 2FA、WebAuthn Authenticator 和 Recovery Authentication Code Form 中包含两个执行的。这些执行默认为 Disabled,它们是可添加到流中的其他 2FA 方法。为用户配置了相应的凭证,请将要求从 Disabled 更改为 alternatives,使其可用。如果用户配置了所有替代凭证类型,则默认会显示具有最高优先级的凭证。但是,将显示 Try Another Way 选项,以便用户具有登录的替代方法。
8.3.1.2. 要求 复制链接链接已复制到粘贴板!
控制操作执行的下拉菜单。
- 必填
- 流中的所有 必需 元素都必须成功执行。如果所需的元素失败,流会终止。
- 替代方案
- 只有单个元素必须成功执行,才能评估成功。因为 Required 流元素足以将流标记为成功,所以包含 Required 流元素的 Alternative 流元素将无法执行。
- Disabled
- 元素不计算将流标记为成功。
- 条件
此要求类型仅在子流上设置。
- Conditional 子流包含执行。这些执行必须评估逻辑语句。
- 如果所有执行评估为 true,则 Conditional 子流充当 必需。
- 如果有任何执行评估为 false,则 Conditional 子流充当 Disabled。
- 如果没有设置执行,Conditional 子流充当 Disabled。
- 如果流包含执行,且流没有设置为 Conditional,则红帽构建的 Keycloak 不会评估执行,并且执行被视为功能 禁用。
8.3.2. 创建流 复制链接链接已复制到粘贴板!
设计流时会应用重要的功能和安全考虑。
要创建流,请执行以下操作:
流程
- 点菜单中的 Authentication。
- 点 Create flow。
您可以复制并修改现有流。单击 "Action list" (行末尾的三个点),单击 Duplicate,然后输入新流的名称。
在创建新流时,您必须首先使用以下选项创建一个顶层流:
- Name
- 流的名称。
- 描述
- 您可以设置为流的描述。
- 顶级流类型
- 流的类型。类型 client 仅用于客户端的身份验证(应用)。对于所有其他情况,请选择 基本的。
创建顶层流
当红帽构建的 Keycloak 创建流时,Red Hat build of Keycloak 会显示 Add step, 和 Add sub-flow 按钮。
空新流
三个因素决定了流和子流的行为。
- 流和子流的结构。
- 流中的执行
- 在子流和执行中设置的要求。
执行具有各种操作,从发送重置电子邮件来验证 OTP。使用 Add step 按钮添加执行。
添加身份验证执行
身份验证执行可以选择性地配置参考值。这可供 身份验证方法参考(AMR)协议映射程序 在 OIDC 访问和 ID 令牌(有关 AMR 声明的更多信息,请参阅 RFC-8176)中填充其声明。当为客户端配置了 身份验证方法参考(AMR) 协议映射器时,它会使用身份验证流程中用户成功完成的任何验证器的参考值填充 amr 声明。
添加验证器引用值
存在两种类型的执行: 自动执行 和交互式执行 。Automatic executions 与 Cookie 执行类似,并将在流中自动执行操作。交互式执行将暂停流以获取输入。执行操作成功将其状态设置为 success。要完成流,至少需要一个 成功状态 的执行。
您可以使用 Add sub-flow 按钮将子流添加到顶层流中。Add sub-flow 按钮显示 Create Execution Flow 页面。此页面类似于 Create Top Level Form 页面。不同之处在于 Flow Type 可以是 basic (默认)或 表单。表单 类型构造一个子流,它为用户生成表单,类似于内置的 Registration 流。子流成功取决于其执行评估的方式,包括它们的子流。如需了解子流如何工作的深入说明,请参阅执行要求部分。???
添加执行后,检查要求具有正确的值。
流中的所有元素在元素旁边都有一个 Delete 选项。一些执行有一个 5 -4 swig 菜单项(齿轮图标)来配置执行。也可以使用 Add step 和 Add sub-flow 链接将执行和子流添加到子流。
由于执行顺序很重要,您可以通过拖动名称来移动执行和子流。
在配置身份验证流时,请确保正确测试您的配置,以确认设置中没有安全漏洞。我们建议您测试各种情况。例如,在身份验证前,请考虑从用户帐户中删除各种凭证时测试用户的身份验证行为。
例如,当双因素验证器(如 OTP Form 或 WebAuthn Authenticator)在流中配置为 REQUIRED,用户没有特定类型的凭证,用户可以在身份验证本身期间设置特定的凭证。这种情况意味着,在身份验证过程中,用户不会通过这个凭证进行身份验证。因此,对于浏览器身份验证,请确保使用一些第一因素凭证(如 Password 或 WebAuthn Passwordless Authenticator)配置您的身份验证流。
8.3.3. 创建无密码浏览器登录流 复制链接链接已复制到粘贴板!
为了说明流的创建,本节描述了创建高级浏览器登录流程。此流的目的是允许用户使用无密码的方式通过 WebAuthn 进行登陆,或使用密码和 OTP 的双因素身份验证进行选择。
流程
- 点菜单中的 Authentication。
- 点 Flows 选项卡。
- 点 Create flow。
-
输入
Browser password-less作为名称。 - 点 Create。
- 单击 Add execution。
- 从列表中选择 Cookie。
- 点击 Add。
- 为 Cookie 身份验证类型选择 alternatives,以将其要求设置为替代方案。
- 单击添加步骤。
- 从列表中选择 Kerberos。
- 点击 Add。
- 单击添加步骤。
- 从列表中选择 Identity Provider Redirector。
- 点击 Add。
- 为 Identity Provider Redirector 验证类型选择 alternatives,以将其要求设置为 alternatives。
- 单击 Add sub-flow。
- 输入 Forms 作为名称。
- 点击 Add。
选择 Alternative for the Forms authentication type 以将其要求设置为 alternative。
浏览器流的常见部分
- 点 Forms execution 的 + 菜单。
- 选择 添加步骤。
- 从列表中选择 Username Form。
- 点击 Add。
在这个阶段,表单需要一个用户名,但没有密码。我们必须启用密码身份验证以避免安全风险。
- 点 Forms 子流的 + 菜单。
- 单击 Add sub-flow。
-
输入
Authentication作为名称。 - 点击 Add。
- 为 Authentication Authentication type 选择 Required 来将其要求设置为 required。
- 点 Authentication 子流的 + 菜单。
- 单击添加步骤。
- 从列表中选择 WebAuthn Passwordless Authenticator。
- 点击 Add。
- 选择 Webauthn Passwordless Authenticator 身份验证类型的替代方案,以将其要求设置为替代。
- 点 Authentication 子流的 + 菜单。
- 单击 Add sub-flow。
-
输入
Password with OTP作为名称。 - 点击 Add。
- 选择 Alternative for the Password with OTP authentication type,以将其要求设置为 alternatives。
- 单击 Password with OTP 子流的 + 菜单。
- 单击添加步骤。
- 从列表中选择 Password Form。
- 点击 Add。
- 为 Password Form 验证类型选择 Required 以将其要求设置为 required。
- 单击 Password with OTP 子流的 + 菜单。
- 单击添加步骤。
- 从列表中选择 OTP Form。
- 点击 Add。
- 为 OTP Form authentication 类型单击 Required,以将其要求设置为 required。
最后,更改绑定。
- 单击屏幕顶部的 Action 菜单。
- 从菜单中选择 绑定流。
- 点 Browser Flow 下拉列表。
- 点击 Save。
无密码浏览器登录
输入用户名后,流可以正常工作:
如果用户有 WebAuthn 免密码凭证记录,他们可以使用这些凭据来直接登录。这是无密码登录。用户也可以选择 Password with OTP,因为 WebAuthn Passwordless execution 和 Password with OTP 流被设为 Alternative。如果它们被设置为 Required,用户必须输入 WebAuthn、password 和 OTP。
如果用户选择带有 WebAuthn 免密码身份验证 的 Try 另一种 链接,用户可以在 Password 和 Passkey (WebAuthn 免密码)之间进行选择。在选择密码时,用户需要继续并使用分配的 OTP 登录。如果用户没有 WebAuthn 凭据,用户必须输入密码,然后是 OTP。如果用户没有 OTP 凭证,则会要求记录凭证。
由于 WebAuthn Passwordless 执行设置为 alternatives 而不是 Required,因此此流不会要求用户注册 WebAuthn 凭据。要让用户具有 Webauthn 凭据,管理员必须向用户添加必要的操作。通过以下方法执行此操作:
创建高级流(如 )可能会产生副作用。例如,如果您启用了为用户重置密码的功能,则可从密码表单访问此密码。在默认的 Reset Credentials 流中,用户必须输入其用户名。由于用户已在 Browser Password-less 流前面输入了用户名,因此红帽构建的 Keycloak 和子优化工具不需要此操作。要更正此问题,您可以:
-
复制
重置凭据流。将其 name 设置为Reset Credentials for password-less,例如: - 单击 Choose user 步骤的 Delete (trash 图标)。
- 在 Action 菜单中,选择 Bind flow,然后从下拉菜单中选择 Reset credentials flow,然后单击 Save
8.3.4. 使用客户端策略选择身份验证流 复制链接链接已复制到粘贴板!
客户端策略 可用于根据特定条件动态选择身份验证流,如请求特定范围或使用 AuthenticationFlowSelectorExecutor 的 ACR (身份验证上下文参考)。
AuthenticationFlowSelectorExecutor 允许您选择适当的身份验证流,并在所选流完成后设置要应用的身份验证级别。
可能的配置涉及将 ACRCondition 与 AuthenticationFlowSelectorExecutor 结合使用。此设置允许您根据请求的 ACR 选择身份验证流,并让使用 ACR 到 LoA Mapping 的令牌中包含的 ACR 值。
如需了解更多详细信息,请参阅 客户端策略。
8.3.5. 使用步骤机制创建浏览器登录流 复制链接链接已复制到粘贴板!
这部分论述了如何使用 step-up 机制创建高级浏览器登录流程。步骤身份验证的目的是允许基于用户的特定身份验证级别访问客户端或资源。
流程
- 点菜单中的 Authentication。
- 点 Flows 选项卡。
- 点 Create flow。
-
输入
Browser Incl Step up Mechanism作为名称。 - 点击 Save。
- 单击 Add execution。
- 从列表中选择 Cookie。
- 点击 Add。
- 为 Cookie 身份验证类型选择 alternatives,以将其要求设置为替代方案。
- 单击 Add sub-flow。
- 输入 Auth Flow 作为名称。
- 点击 Add。
- 点 Alternative,Auth Flow 验证类型将它的 requirement 设置为 alternative。
现在,您可以为第一个身份验证级别配置流。
- 单击 Auth Flow 的 + 菜单。
- 单击 Add sub-flow。
-
输入
1st Condition Flow作为名称。 - 点击 Add。
- 点 1st Condition Flow 验证类型的 Conditional 将其要求设置为 conditional。
- 点 1st Condition Flow 的 + 菜单。
- 单击 Add condition。
- 从列表中选择 Conditional - Level Of Authentication。
- 点击 Add。
- 对于 Conditional - Level Of Authentication authentication 类型,点 Required 来将其要求设置为 required。
- 点 wagon wagon (gear 图标)。
-
输入
Level 1作为别名。 -
在级别验证(LoA)中输入
1。 -
将 Max Age 设置为 36000。这个值以秒为单位,相当于 10 小时,这是在 realm 中设置的默认
SSO Session Max超时。因此,当用户使用此级别进行身份验证时,后续的 SSO 登录可能会重复使用这个级别,用户不需要在此级别进行身份验证,直到用户会话结束前(默认为 10 小时)。 点 Save
配置第一个身份验证级别的条件
- 点 1st Condition Flow 的 + 菜单。
- 单击添加步骤。
- 从列表中选择 Username Password Form。
- 点击 Add。
现在,您可以为第二个身份验证级别配置流。
- 单击 Auth Flow 的 + 菜单。
- 单击 Add sub-flow。
-
输入
2nd Condition Flow作为一个别名。 - 点击 Add。
- 为 2nd Condition Flow 验证类型点 conditional,将其要求设置为 conditional。
- 点 2nd Condition Flow 的 + 菜单。
- 单击 Add condition。
- 从项目列表中选择 Conditional - Level Of Authentication。
- 点击 Add。
- 对于 Conditional - Level Of Authentication authentication 类型,点 Required 来将其要求设置为 required。
- 点 wagon wagon (gear 图标)。
-
输入
Level 2作为别名。 -
在身份验证级别(LoA)输入
2。 - 将 Max Age 设置为 0。因此,在用户进行身份验证时,此级别仅适用于当前身份验证,但不适用于任何后续 SSO 身份验证。因此,在请求此级别时,用户始终需要与这个级别再次进行身份验证。
点 Save
为第二个身份验证级别配置条件
- 点 2nd Condition Flow 的 + 菜单。
- 单击添加步骤。
- 从列表中选择 OTP Form。
- 点击 Add。
- 为 OTP Form authentication 类型单击 Required,以将其要求设置为 required。
最后,更改绑定。
- 单击屏幕顶部的 Action 菜单。
- 从列表中选择 Bind flow。
- 从下拉菜单中选择 Browser Flow。
- 点击 Save。
使用步骤机制进行浏览器登录
请求特定的身份验证级别
要使用步骤机制,您可以在身份验证请求中指定请求的身份验证级别(LoA)。claim 参数用于此目的:
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
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 指定:
Red Hat build of Keycloak javascript 适配器支持轻松构建此 JSON 并将其发送到登录请求。如需了解更多详细信息,请参阅 安全应用程序部分中的 Keycloak JavaScript 适配器。
您还可以使用更简单的参数 acr_values 而不是 claims 参数来请求特定级别(非合规)。这在 OIDC 规范中提到。
您还可以为特定客户端配置默认级别,当参数 acr_values 或带有 acr 声明 的参数声明时使用。详情请参阅 客户端 ACR 配置。
要请求 acr_values 作为文本(如 金级值),您需要配置 ACR 和 LoA 之间的映射。可以在域级别(推荐)或客户端级别进行配置。有关配置,请参阅 ACR 到 LoA 映射。
详情请查看 官方 OIDC 规格。
流逻辑
上述配置的身份验证流程的逻辑如下:
如果客户端需要高的身份验证级别,即身份验证 2 级别(LoA 2),用户必须执行完整的双因素身份验证:Username/Password + OTP。但是,如果用户在 Red Hat build of Keycloak (使用用户名和密码登录)中已有一个会话,则只要求用户进行第二个身份验证因素(OTP)。
条件中的 Max Age 选项决定了后续身份验证级别有效的时长(多少秒)。此设置有助于决定是否在后续身份验证过程中再次显示身份验证因素。如果 声明 或 acr_values 参数请求特定的级别 X,并且用户已经使用级别 X 进行身份验证,但它已过期(例如,最大期限配置为在 310 秒前进行身份验证),则用户会被要求使用特定级别重新验证。但是,如果级别尚未过期,则用户将自动被视为使用该级别的身份验证。
将 Max Age 与值 0 表示,该特定级别仅对此单一身份验证有效。因此,请求该级别的每个重新身份验证都需要与该级别再次进行身份验证。这对需要在应用中需要更高的安全性的操作(如发送付款)以及始终需要使用特定级别进行身份验证的操作很有用。
请注意,当通过用户的浏览器将登录请求从客户端发送到 Red Hat build of Keycloak 时,在 URL 中的用户可能会更改 声明 或 acr_values 等参数。如果客户端使用 PAR (Pushed 授权请求)、请求对象或阻止用户重写 URL 中的参数的其他机制,则可以缓解这种情况。因此,在身份验证后,建议客户端检查 ID Token 来再次检查令牌中的 cr 对应于预期的级别。
如果没有根据参数请求显式级别,红帽构建的 Keycloak 需要使用身份验证流程中找到的第一个 LoA 条件进行身份验证,如上例中的 Username/Password。当用户已使用该级别且该级别过期而进行身份验证时,用户不需要重新验证,但令牌中的 acr 将具有值 0。如 OIDC Core 1.0 规格的第 2 节中所述,这个结果只被视为基于 长期的浏览器 Cookie 的身份验证。
在用户首次验证过程中,始终执行第一个带有 Conditional - Level Of Authentication 的子流(不包括请求的级别),因为用户还没有任何级别。因此,我们建议第一个级别子流包含用户身份验证所需的最小验证器。此外,确保带有不同值 Conditional - Level Of Authentication 的子流以最低顺序排序,如上例中所示。例如,如果您使用级别 2 配置子流,然后添加另一个带有级别 1 的子流,则级别 2 子流将始终在第一个验证中要求,这可能是所需的行为。
当管理员指定多个流,各自设置不同的 LoA 级别,并将流分配给不同的客户端时,可能会出现冲突情况。但是,该规则始终相同:如果用户具有特定级别,它只需要该级别才能连接到客户端。管理员最多需要确保 LoA 是一致的。
具有级别身份验证的逐步身份验证适用于各个级别需要之前级别的所有身份验证方法的用例。例如,级别 X 必须始终包含级别 X-1 所需的所有验证方法。对于特定级别(如级别 3)的用例,需要与之前级别不同的身份验证方法,可能更适合使用 ACR 到特定流的映射。如需了解更多详细信息,请参阅使用客户端策略选择身份验证流。
示例情境
- 对于级别 1 条件,最大 Age 配置为 300 秒。
-
在不请求任何 acr 的情况下发送登录请求。将使用级别 1,用户需要使用用户名和密码进行身份验证。令牌将具有
acr=1。 -
另一个登录请求会在 100 秒后发送。由于 SSO,用户会自动进行身份验证,并且令牌将返回
acr=1。 -
另一登录请求在 201 秒后发出(自 2 中的身份验证后计算为 301 秒)由于 SSO,用户会自动进行身份验证,但令牌将因为级别 1 被视为过期而返回
cr=0。 -
发送另一个登录请求,但现在它将在
claims参数中明确请求 ACR 级别 1。用户将被要求通过用户名/密码重新进行身份验证,然后在令牌中返回acr=1。
令牌中的 ACR 声明
ACR 声明通过在 acr 客户端范围中定义的 acr loa level 协议映射程序添加到令牌中。此客户端范围是域默认客户端范围,因此将添加到域中的所有新创建的客户端。
如果您不希望令牌内部的 acr 声明或需要一些自定义逻辑来添加它,您可以从客户端中删除客户端范围。
请注意,当登录请求时,使用请求 acr 的 claims 参数启动请求时,Red Hat build of Keycloak 将始终返回一个指定的级别。如果无法返回指定级别之一(例如,如果请求的级别未知或大于身份验证流中配置的条件),则红帽构建的 Keycloak 将抛出错误。
8.3.6. 客户端请求的注册或重置凭证 复制链接链接已复制到粘贴板!
通常,当用户从客户端应用程序重定向到 Keycloak 的红帽构建时,会触发 浏览器 流。当用户启用了域 注册 且用户点击登录屏幕上的 Register 时,用户可以注册此流。另外,如果为域启用了 Forget 密码,用户可以单击登录屏幕上的 Forget 密码,这会触发 Reset credentials 流,用户可以在电子邮件地址确认后重置凭证。
有时,客户端应用程序可以直接将用户重定向到 Registration 屏幕或重置 凭据流。当用户点击正常的登录屏幕上的 Register 或 Forget 密码时,生成的操作将匹配 的操作。自动重定向到 registration 或 reset-credentials 屏幕,如下所示:
-
当客户端希望用户直接重定向到注册时,OIDC 客户端应在登录请求中添加参数
prompt=create。作为弃用的替代方案,客户端可以使用/registrations替换 OIDC 登录 URL 路径(/auth)中的最后一个片段。因此,完整的 URL 可能类似如下:https://keycloak.example.com/realms/your_realm/protocol/openid-connect/registrations。建议使用prompt=create,因为它是 规范标准。 -
当客户端希望用户直接重定向到
Reset 凭证流时,OIDC 客户端应该将 OIDC 登录 URL 路径(/auth)中的最后一个片断替换为/forgot-credentials。
前面的步骤是客户端直接请求注册或 reset-credentials 流唯一支持的方法。为了安全起见,不适用于客户端应用程序来绕过 OIDC/SAML 流,并直接重定向到其他红帽 Keycloak 端点(如 /realms/realm_name/login-actions 或 /realms/realm_name/broker)。