第 10 章 SSO 协议


本节讨论身份验证协议,红帽构建的 Keycloak 身份验证服务器,以及由红帽构建的 Keycloak 身份验证服务器保护的应用程序如何与这些协议交互。

10.1. OpenID Connect

OpenID Connect (OIDC)是一个身份验证协议,它是 OAuth 2.0 的扩展。

OAuth 2.0 是一个用于构建授权协议且不完整的框架。但是,OIDC 是使用 Json Web Token (JWT)标准的完整身份验证和授权协议。JWT 标准定义了身份令牌 JSON 格式和方法,以便以紧凑和 Web 友好的方式进行数字签名和加密数据。

通常,OIDC 实现了两个用例。第一个情况是要求红帽构建的 Keycloak 服务器验证用户身份的应用程序。成功登录后,应用程序会收到 身份令牌访问令牌身份令牌 包含用户信息,包括用户名、电子邮件和配置文件信息。realm 以数字签名的方式为 访问令牌 签名,其中包含应用程序用来决定应用程序中可以访问的访问信息(如用户角色映射)。

第二个用例是访问远程服务的客户端。

  • 客户端从红帽构建的 Keycloak 请求访问令牌,以代表用户调用远程服务。
  • 红帽 Keycloak 的构建会验证用户,并要求用户同意授予对请求客户端的访问权限。
  • 客户端接收由域数字签名的访问令牌
  • 客户端使用 访问令牌 在远程服务上发出 REST 请求。
  • 远程 REST 服务提取 访问令牌
  • 远程 REST 服务验证令牌签名。
  • 远程 REST 服务根据令牌中的访问信息来决定,以处理或拒绝请求。

10.1.1. OIDC 身份验证流

OIDC 有几个方法或流,客户端或应用程序可以用来验证用户并接收 身份和 访问令牌。该方法取决于请求访问的应用或客户端的类型。

10.1.1.1. 授权代码流

授权代码流是基于浏览器的协议,适合验证和授权基于浏览器的应用程序。它使用浏览器重定向来获取身份访问令牌。

  1. 用户使用浏览器连接到应用程序。应用程序检测到用户没有登录到应用程序。
  2. 应用程序将浏览器重定向到红帽构建的 Keycloak 进行验证。
  3. 应用在浏览器中将回调 URL 作为查询参数传递。红帽构建的 Keycloak 在成功身份验证时使用参数。
  4. 红帽 Keycloak 的构建会验证用户,并创建一个一次性的、短期的临时代码。
  5. 红帽构建的 Keycloak 使用回调 URL 重定向到应用程序,并在回调 URL 中添加临时代码作为查询参数。
  6. 应用程序提取临时代码,并对红帽构建的 Keycloak 发出后台 REST 调用,以交换 身份和 访问和 刷新令牌 的代码。为防止重播攻击,无法多次使用临时代码。
注意

在该令牌生命周期内,系统容易受到 stolen 令牌的影响。由于安全性和可伸缩性的原因,访问令牌通常被设置为快速过期,因此后续令牌请求会失败。如果令牌过期,应用程序可以使用登录协议发送的额外 刷新令牌 获取新的访问令牌。

机密 客户端在交换令牌临时代码时提供客户端机密。不需要公共客户端来提供客户端 secret。当 HTTPS 被严格强制时,公共客户端安全,并且严格控制为客户端注册的 URI。HTML5/JavaScript 客户端必须是 公共 客户端,因为无法安全地将客户端 secret 传送到 HTML5/JavaScript 客户端。如需了解更多详细信息,请参阅管理客户端 章节。

红帽构建的 Keycloak 还支持代码 交换规范的概念验证

10.1.1.2. 隐式流

Implicit Flow 是一个基于浏览器的协议。它与授权代码流类似,但请求较少,且没有刷新令牌。

注意

当令牌通过重定向 URI 传输时,浏览器历史记录中 的访问令牌 可能会泄漏(请参阅以下)。

另外,此流并不为客户端提供刷新令牌。因此,访问令牌必须长期有效,或者用户必须在过期时重新进行身份验证。

我们不推荐使用这个流程。此流被支持,因为它在 OIDC 和 OAuth 2.0 规格中。

协议按如下方式工作:

  1. 用户使用浏览器连接到应用程序。应用程序检测到用户没有登录到应用程序。
  2. 应用程序将浏览器重定向到红帽构建的 Keycloak 进行验证。
  3. 应用在浏览器中将回调 URL 作为查询参数传递。红帽构建的 Keycloak 在身份验证成功后使用查询参数。
  4. Red Hat build of Keycloak 验证用户并创建 身份和 访问令牌。红帽构建的 Keycloak 使用回调 URL 重定向到应用程序,并在回调 URL 中将 身份和 访问令牌 添加为查询参数。
  5. 应用从回调 URL 中提取 身份和 访问令牌

10.1.1.3. 资源所有者密码凭证授权(直接访问授予)

REST 客户端使用 直接访问授予 代表用户获取令牌。它是包含以下内容的 HTTP POST 请求:

  • 用户的凭据。凭据以表单参数的形式发送。
  • 客户端的 id。
  • 客户端机密(如果它是机密客户端)。

HTTP 响应包含 身份访问刷新令牌

10.1.1.4. 客户端凭证授权

Client Credentials Grant 根据与客户端关联的服务帐户的元数据和权限创建一个令牌,而不是获取代表外部用户的令牌。REST 客户端使用客户端 凭据授予

如需更多信息,请参阅服务帐户章节。

10.1.1.5. 刷新令牌授权

默认情况下,红帽构建的 Keycloak 会从大多数流返回令牌响应中的刷新令牌。有些例外是隐式流或客户端凭证。

刷新令牌与 SSO 浏览器会话的用户会话相关联,可以在用户会话的生命周期内有效。但是,该客户端应为每个指定间隔发送一次 refresh-token 请求。否则,会话可被视为 "idle",并可过期。如需更多信息 ,请参阅 timeout 部分

Red Hat build of Keycloak 支持 离线令牌,这通常在客户端需要使用刷新令牌时使用,即使对应的浏览器 SSO 会话已过期。

10.1.1.5.1. 刷新令牌轮转

可以指定刷新令牌在使用后被视为无效。这意味着,客户端必须始终从最后的刷新响应保存刷新令牌,因为旧的刷新令牌已使用,红帽构建的 Keycloak 不再被视为有效。这可以通过使用 Revoke Refresh token 选项进行设置,如 timeout 部分中指定的。???

Red Hat build of Keycloak 还支持没有刷新令牌轮转的情况。在这种情况下,登录过程中会返回刷新令牌,但后续来自 refresh-token 请求的响应不会返回新的刷新令牌。建议在 FAPI 2 草案规格中的 FAPI 2 草案规范 中的实例进行这个实践。https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/securing_applications_and_services_guide/在 Red Hat build of Keycloak 中,可以使用 客户端策略 跳过刷新令牌轮转。您可以将 executor suppress-refresh-token-rotation 添加到某些客户端配置集,并将客户端策略配置为触发的配置集,这意味着对于那些客户端刷新令牌轮转会被跳过。

10.1.1.6. 设备授权

这供在具有有限输入功能或缺少合适的浏览器的互联网连接设备中运行客户端使用。以下是协议的简要概述:

  1. 应用程序请求红帽构建的 Keycloak 是一个设备代码和用户代码。红帽构建的 Keycloak 创建设备代码和用户代码。红帽构建的 Keycloak 返回一个响应,包括设备代码和用户代码到应用程序。
  2. 应用为用户提供用户代码和验证 URI。用户访问验证 URI 以使用另一个浏览器进行身份验证。您可以定义一个简短的 verification_uri,它将被重定向到红帽构建的 Keycloak 验证 URI (/realms/realm_name/device)到 Red Hat build of Keycloak - fe in proxy。
  3. 应用程序重复轮询红帽构建的 Keycloak,以确定用户是否完成了用户授权。如果完成了用户身份验证,应用程序会交换 身份访问刷新令牌的设备代码。

10.1.1.7. 客户端启动后向通道身份验证授权

此功能供希望通过直接与 OpenID 提供程序通信来发起身份验证流程的客户端使用,而无需通过用户的浏览器(如 OAuth 2.0 的授权代码授权)进行重定向。以下是协议的简要概述:

  1. 客户端请求红帽构建的 Keycloak auth_req_id,用于标识客户端发出的身份验证请求。Red Hat build of Keycloak 创建 auth_req_id。
  2. 收到这个 auth_req_id 后,这个客户端需要重复轮询红帽构建的 Keycloak,以获取来自红帽构建的 Keycloak 的访问令牌、刷新令牌和 ID 令牌,以便为 auth_req_id 返回。

管理员可以将客户端初始后端身份验证(CIBA)相关操作配置为每个域的 CIBA 策略

另外,请参阅 Red Hat build of Keycloak 文档的其它位置,如 Backchannel Authentication EndpointClient Initiated Backchannel Authentication Grant in secure apps 部分。

10.1.1.7.1. CIBA 策略

管理员在 管理控制台 上执行以下操作:

  • 打开 Authentication CIBA Policy 选项卡。
  • 配置项目并单击 保存

下面是可配置的项目及其描述。

Configuration描述

Backchannel Token Delivery 模式

指定 CD (继续设备)如何获取身份验证结果和相关令牌。有三种模式:"poll"、"ping"和"push"。红帽构建的 Keycloak 只支持 "poll"。默认设置为 "poll"。这个配置是必需的。如需了解更多详细信息,请参阅 CIBA 规格

过期

收到身份验证请求后的 "auth_req_id" 的过期时间(以秒为单位)。默认设置为 120。这个配置是必需的。如需了解更多详细信息,请参阅 CIBA 规格

Interval(间隔)

CD (继续设备)在轮询请求到令牌端点之间需要等待的时间间隔(以秒为单位)。默认设置为 5。此配置是可选的。如需了解更多详细信息,请参阅 CIBA 规格

请求身份验证的用户 Hint

识别请求身份验证的最终用户的方法。默认设置为 "login_hint"。有三种模式:"login_hint"、"login_hint_token"和"id_token_hint"。Red Hat build of Keycloak 只支持 "login_hint"。这个配置是必需的。如需了解更多详细信息,请参阅 CIBA 规格

10.1.1.7.2. 供应商设置

CIBA 授权使用以下两个供应商。

  1. 身份验证频道供应商:提供红帽构建的 Keycloak 和实际通过 AD 验证用户的实体之间的通信。
  2. User Resolver Provider: get UserModel of Red Hat build of Keycloak from the client information provided the user.

红帽构建的 Keycloak 有两个默认供应商。但是,管理员需要设置 Authentication Channel 供应商,如下所示:

kc.[sh|bat] start --spi-ciba-auth-channel-ciba-http-auth-channel-http-authentication-channel-uri=https://backend.internal.example.com

下面是可配置的项目及其描述。

Configuration描述

http-authentication-channel-uri

指定实际通过 AD (验证设备)验证用户的实体的 URI。

10.1.1.7.3. 身份验证频道供应商

CIBA 标准文档没有指定如何验证 AD 用户。因此,它可能会由产品自由裁量实施。红帽构建的 Keycloak 将此身份验证委派给外部身份验证实体。为了与身份验证实体通信,红帽构建的 Keycloak 提供身份验证频道供应商。

红帽构建的 Keycloak 实施假定身份验证实体由红帽构建的 Keycloak 管理员控制,以便红帽构建的 Keycloak 信任身份验证实体。不建议使用 Red Hat build of Keycloak 管理员控制的身份验证实体。

身份验证频道供应商以 SPI 供应商的形式提供,以便红帽构建的 Keycloak 用户可以实施自己的供应商来满足其环境。红帽构建的 Keycloak 提供名为 HTTP Authentication Channel Provider 的默认供应商,该供应商使用 HTTP 与身份验证实体通信。

如果红帽构建的 Keycloak 用户希望使用 HTTP 身份验证频道供应商,则需要知道其在红帽构建的 Keycloak 和由以下两个部分组成的身份验证实体之间的合同。

身份验证委派请求/响应
红帽构建的 Keycloak 将身份验证请求发送到身份验证实体。
身份验证结果通知/ACK
身份验证实体通知红帽构建的 Keycloak 身份验证的结果。

身份验证委派请求/响应由下列消息传递组成:

身份验证委派请求
该请求从红帽构建的 Keycloak 发送到身份验证实体,以请求 AD 进行用户身份验证。
POST [delegation_reception]
  • Headers
Name描述

Content-Type

application/json

消息正文是 json 格式的。

授权

bearer [token]

当身份验证实体通知红帽构建的 Keycloak 身份验证结果时,会使用 [token]。

  • 参数
类型Name描述

路径

delegation_reception

身份验证实体提供的端点来接收委托请求

  • Body
Name描述

login_hint

它告知 AD 验证的身份验证实体。
默认情况下,它是用户的"username"。
此字段是必需的,由 CIBA 标准文档定义。

scope

它告知身份验证实体对经过身份验证的用户的同意范围。
此字段是必需的,由 CIBA 标准文档定义。

is_consent_required

它显示了身份验证实体是否需要从经过身份验证的用户获得该范围的同意。
此字段是必需的。

binding_message

其值应该在 CD 和 AD 的 UI 中显示,以便用户识别 AD 是由 CD 触发的身份验证。
此字段是可选的,由 CIBA 标准文档定义。

acr_values

它告知从 CD 中请求的身份验证上下文类参考。
此字段是可选的,由 CIBA 标准文档定义。

身份验证委派响应

响应从身份验证实体返回至红帽构建的 Keycloak,以通知身份验证实体从红帽构建的 Keycloak 收到身份验证请求。

  • 响应
HTTP 状态代码描述

201

它通知红帽构建的 Keycloak 接收身份验证委托请求。

身份验证结果通知/ACK 由以下消息传递组成:

身份验证结果通知
身份验证实体将身份验证请求的结果发送到红帽构建的 Keycloak。
POST /realms/[realm]/protocol/openid-connect/ext/ciba/auth/callback
  • Headers
Name描述

Content-Type

application/json

消息正文是 json 格式的。

授权

bearer [token]

[token] 必须是 Red Hat build of Keycloak in Authentication Delegation Request 中的身份验证实体。

  • 参数
类型Name描述

路径

realm

realm 名称

  • Body
Name描述

status

它告知 AD 用户身份验证的结果。
它必须是以下状态之一:
SUCCEED : AD 的身份验证已成功完成。
UNAUTHORIZED : AD 的身份验证尚未完成。
CANCELLED : AD 的身份验证已被用户取消。

身份验证结果 ACK

响应从 Red Hat build of Keycloak 返回给身份验证实体,以通知红帽构建的 Keycloak 收到来自身份验证实体的 AD 用户身份验证的结果。

  • 响应
HTTP 状态代码描述

200

它通知身份验证实体接收身份验证结果通知。

10.1.1.7.4. 用户解析器提供程序

即使同一用户,其表示在每个 CD 中可能会有所不同,红帽构建的 Keycloak 和身份验证实体也会不同。

对于 CD,红帽构建的 Keycloak 和身份验证实体无法识别同一用户,此用户解析器提供程序会在它们中转换自己的用户表示。

用户 Resolver Provider 作为 SPI 供应商提供,以便红帽构建的 Keycloak 用户可以实施自己的提供程序来满足其环境。红帽构建的 Keycloak 提供名为 Default User Resolver Provider 的默认供应商,其具有以下特征:

  • 仅支持 login_hint 参数,并用作默认值。
  • 红帽构建的 Keycloak 中的 UserModel 用户名 用于代表 CD、红帽构建的 Keycloak 和身份验证实体上的用户。

10.1.2. OIDC Logout

OIDC 有四个与注销机制相关的规格:

同样,因为所有这都是在 OIDC 规格中所描述的,因此我们只会在此处提供简短概述。

10.1.2.1. 会话管理

这是基于浏览器的注销。应用程序定期从红帽构建的 Keycloak 获取会话状态信息。当在红帽构建的 Keycloak 中终止会话时,应用程序会通知并触发它自己的注销。

10.1.2.2. RP-Initiated Logout

这也是一个基于浏览器的注销,其中注销首先通过将用户重定向到红帽构建的 Keycloak 的特定端点。当用户点击某些应用程序的页面中的 Log Out 链接(之前使用 Red Hat build of Keycloak 验证用户)时,通常会发生此重定向。

用户重定向到 logout 端点后,红帽构建的 Keycloak 将向客户端发送注销请求,使它们无效,并在注销过程完成后可能会将用户重定向到一些 URL。在没有使用 id_token_hint 参数时,可能会要求用户确认注销。注销后,只要以参数形式提供,用户会自动重定向到指定的 post_logout_redirect_uri 中。请注意,当包含 post_logout_redirect_uri 时,您需要包含 client_idid_token_hint 参数。另外,post_logout_redirect_uri 参数需要匹配客户端 配置中指定的 Valid Post Logout Redirect URI 之一。

根据客户端配置,可以通过前端或后端通道将注销请求发送到客户端。对于依赖上一节中描述的 Session Management 的前端浏览器客户端,红帽构建的 Keycloak 不需要向它们发送任何注销请求;这些客户端会自动检测到浏览器中的 SSO 会话。

10.1.2.3. front-channel Logout

要将客户端配置为通过前端接收注销请求,请查看 Front-Channel Logout 客户端设置。使用此方法时,请考虑以下几点:

  • 退出红帽构建的 Keycloak 给客户端的请求会依赖于浏览器和嵌入的(在为注销页面呈现的)中的请求。
  • 通过基于 iframes,前端通道退出可能受到内容安全策略(CSP)的影响,并且注销请求可能会被阻止。
  • 如果用户在呈现注销页面之前关闭浏览器,或在将请求实际发送到客户端之前关闭浏览器,则客户端上的会话可能不会无效。
注意

考虑使用 Back-Channel Logout,因为它提供了更加可靠和安全的方法,以注销用户并终止其客户端上的会话。

如果没有通过 front-channel logout 启用客户端,则红帽构建的 Keycloak 将试图使用 Back-Channel Logout URL 通过后端通道发送注销请求。如果没有定义,服务器将回退到使用 Admin URL

10.1.2.4. Backchannel Logout

这是一个基于非浏览器的注销,它使用红帽构建的 Keycloak 和客户端之间的直接通道通信。Red Hat build of Keycloak 将包含注销令牌的 HTTP POST 请求发送到登录到红帽构建的 Keycloak 的所有客户端。这些请求发送到红帽构建的 Keycloak 中注册的后通道注销 URL,并应在客户端一侧触发退出。

10.1.3. 红帽构建的 Keycloak 服务器 OIDC URI 端点

以下是红帽构建的 Keycloak 发布的 OIDC 端点列表。当非红帽构建的 Keycloak 客户端适配器使用 OIDC 与身份验证服务器通信时,可以使用这些端点。它们都是相对 URL。URL 的根由 HTTP (S)协议、主机名和可选路径组成:例如

https://localhost:8080
/realms/{realm-name}/protocol/openid-connect/auth
用于在授权代码流中获取临时代码,或使用 Implicit Flow, Direct Grants, 或 Client Grants 获取令牌。
/realms/{realm-name}/protocol/openid-connect/token
授权代码流使用它来将临时代码转换为令牌。
/realms/{realm-name}/protocol/openid-connect/logout
用于执行注销。
/realms/{realm-name}/protocol/openid-connect/userinfo
用于 OIDC 规格中描述的用户 Info 服务。
/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
这是 Client Initiated Backchannel Authentication Grant 的 URL 端点,以获取一个 auth_req_id,用于标识客户端发出的身份验证请求。
/realms/{realm-name}/protocol/openid-connect/logout/backchannel-logout
这是执行 OIDC 规格中描述的反向通道注销的 URL 端点。

在所有这些部分中,将 {realm-name} 替换为域的名称。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.