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