第 13 章 管理 OpenID Connect 和 SAML 客户端


客户端是可以请求用户身份验证的实体。客户端以两种形式提供。第一个类型的客户端是希望参与单点登录的应用程序。这些客户端只希望红帽构建的 Keycloak 为其提供安全性。其他类型的客户端是请求访问令牌之一,以便它能够代表经过身份验证的用户调用其他服务。本节讨论了有关配置客户端以及进行各种方法的各方面。

13.1. 管理 OpenID Connect 客户端

OpenID Connect 是推荐的协议来保护应用程序。它设计为网络友好型设计,最适合 HTML5/JavaScript 应用程序。

13.1.1. 创建 OpenID Connect 客户端

要保护使用 OpenID 连接协议的应用程序,请创建一个客户端。

流程

  1. 点菜单中的 Clients
  2. 单击 Create client

    创建客户端

    Create Client

  3. Client type 设置为 OpenID Connect
  4. 输入 客户端 ID。

    这个 ID 是一个字母数字字符串,用于 OIDC 请求以及红帽构建的 Keycloak 数据库来识别客户端。

  5. 为客户端提供 Name

    如果您计划本地化此名称,请设置替换字符串值。例如,字符串值,如 ${myapp}。如需更多信息 ,请参阅服务器开发人员指南

  6. 点击 Save

此操作将创建客户端,并带您进入 Settings 选项卡,您可以在其中 执行基本配置

13.1.2. 基本配置

Settings 选项卡包含用于配置此客户端的许多选项。

设置标签页

Settings tab

13.1.2.1. 常规设置

客户端 ID
OIDC 请求中使用的字母数字 ID 字符串,以及红帽构建的 Keycloak 数据库来识别客户端。
Name
红帽构建的 Keycloak UI 屏幕中的客户端名称。要本地化名称,请设置替换字符串值。例如,字符串值,如 ${myapp}。如需更多信息 ,请参阅服务器开发人员指南
描述
客户端的描述。此设置也可以本地化。
始终在控制台中显示
即使此用户没有活动的会话,也始终在帐户控制台中列出此客户端。

13.1.2.2. 访问设置

根 URL
如果红帽构建的 Keycloak 使用任何配置的相对 URL,则该值会添加到其中。
主页 URL
提供默认 URL,当 auth 服务器需要重定向或链接到客户端时。
有效的 Redirect URI

必填字段。输入 URL 模式,然后单击 + 以删除现有 URL,然后单击 Save完全(区分大小写)字符串匹配用于比较有效的重定向 URI。

您可以在 URL 模式末尾使用通配符。例如 http://host.com/path/*。为避免安全问题,如果传递的重定向 URI 包含 userinfo 部分,或者 其路径 管理对父目录(/../)的访问,则不会执行通配符比较,但标准和安全完全匹配。

完整通配符 * 有效重定向 URI 也可以配置为允许任何 httphttps 重定向 URI。请不要在生产环境中使用它。

专用重定向 URI 模式通常更为安全。如需更多信息 ,请参阅非特定 Redirect URI

Web Origins

输入 URL 模式并点击 + 以删除现有 URL。点 Save。

此选项处理 Cross-Origin Resource Sharing (CORS)。如果浏览器 JavaScript 尝试 AJAX HTTP 请求到域与 JavaScript 代码来自的服务器不同,则请求必须使用 CORS。服务器必须处理 CORS 请求,否则浏览器将不会显示或允许处理请求。此协议可防止 XSS、CSRF 和其他基于 JavaScript 的攻击。

此处列出的域 URL 嵌入到发送到客户端应用程序的访问令牌中。客户端应用使用此信息来决定是否允许在其上调用 CORS 请求。只有 Red Hat build of Keycloak 客户端适配器支持此功能。如需更多信息,请参阅 保护应用程序和服务指南

管理 URL
客户端的回调端点。服务器使用此 URL 进行回调,如推送撤销策略、执行反向通道注销和其他管理操作。对于红帽构建的 Keycloak servlet 适配器,此 URL 可以是 servlet 应用程序的 root URL。如需更多信息,请参阅 保护应用程序和服务指南

13.1.2.3. 功能配置

客户端身份验证

OIDC 客户端的类型。

  • ON

    对于执行浏览器登录的服务器端客户端,并在进行访问令牌请求时要求客户端 secret。此设置应该用于服务器端应用程序。

  • OFF

    用于执行浏览器登录的客户端。由于无法确保 secret 可以与客户端安全保存,因此务必要通过配置正确的重定向 URI 来限制访问。

授权
启用或禁用此客户端的细粒度授权支持。
标准流
如果启用,此客户端可以使用 OIDC 授权代码流
直接访问授予
如果启用,此客户端可以使用 OIDC Direct Access Grants
隐式流
如果启用,此客户端可以使用 OIDC Implicit 流
服务帐户角色
如果启用,此客户端可以向红帽构建 Keycloak 进行身份验证,并检索专用于此客户端的访问令牌。在 OAuth2 规范中,这 支持此客户端的客户端 凭证授予。
标准令牌交换
如果启用,此客户端可以使用 标准令牌交换
Auth 2.0 设备授权
如果启用,此客户端可以使用 OIDC 设备授权
OIDC CIBA Grant
如果启用,此客户端可以使用 OIDC Client Initiated Backchannel Authentication Grant

13.1.2.4. 登录设置

登录主题
用于 login、OTP、授予注册和忘记密码页面的主题。
需要同意

如果启用,用户必须同意客户端访问。

用于执行浏览器登录的客户端。由于无法确保 secret 可以与客户端安全保存,因此务必要通过配置正确的重定向 URI 来限制访问。

在屏幕上显示客户端

如果 Consent RequiredOff,则应用此开关。

  • 同意屏幕将仅包含与配置的客户端范围对应的同意。

  • On

    此客户端本身的同意屏幕上也会有一个项。

客户端同意屏幕文本
如果启用了 屏幕上的 Consent required 和 Display client。包含有关此客户端权限的同意屏幕上的文本。

13.1.2.5. 退出设置

前端频道退出
如果启用了 Front Channel Logout,应用程序应该可以根据 OpenID Connect Front-Channel Logout 规格通过前端频道注销用户。如果启用,您还应提供 Front-Channel Logout URL
front-channel logout URL
红帽构建的 Keycloak 用于通过前端向客户端发送注销请求的 URL。如果没有提供,则默认为 Home URL。只有在 Front channel logout 选项为 ON 时,这个选项才适用。
前端注销会话所需的
指定在使用 Front-channel Logout URL 时,Logout 请求中是否包含 sid (会话 ID)和 iss (issuer)参数。
Backchannel logout URL
当注销请求发送到此域(通过 end_session_endpoint)时,会导致客户端自行注销。注销是通过发送注销令牌,如 OIDC Backchannel logout 规格中指定的。如果省略,则注销请求可能会以特定于红帽构建的 Keycloak 适配器的格式发送到指定的 Admin URL (如果配置)。如果没有配置 Admin URL,则不会向客户端发送注销请求。只有在 Front channel logout 选项为 OFF 时,这个选项才适用。
需要 Backchannel logout 会话
指定在使用 Backchannel Logout URL 时,Logout Token 中是否包含会话 ID 声明。
Backchannel logout revoke offline sessions
指定在使用 Backchannel Logout URL 时,Logout Token 中是否包含 revoke_offline_access 事件。红帽构建的 Keycloak 将在使用这个事件接收 Logout Token 时撤销离线会话。

13.1.3. 高级配置

Settings 选项卡中完成字段后,您可以使用其他标签页执行高级配置。

13.1.3.1. 高级标签页

当您点 Advanced 选项卡时,会显示其他字段。有关特定字段的详情,请点击该字段的问号图标。但是,本节将详细介绍某些字段。

13.1.3.2. 精细的 OpenID Connect 配置

徽标 URL

引用客户端应用程序的徽标的 URL。

策略 URL

Relying Party Client 为 End-User 提供的 URL,用于读取配置集数据的使用方式。

服务 URL 术语

Relying Party Client 提供给最终用户以阅读有关 Relying Party 服务条款的 URL。

签名和加密的 ID 令牌支持

红帽构建的 Keycloak 可以根据 Json Web 加密(JWE)规范加密 ID 令牌。管理员决定是否为每个客户端加密 ID 令牌。

用于加密 ID 令牌的密钥是内容加密密钥(CEK)。红帽构建的 Keycloak 和客户端必须协商使用哪个 CEK 以及它是如何提供的。确定 CEK 的方法是密钥管理模式。红帽构建的 Keycloak 支持的密钥管理模式是密钥加密。

在密钥加密中:

  1. 客户端生成非对称加密密钥对。
  2. 公钥用于加密 CEK。
  3. Red Hat build of Keycloak 为每个 ID 令牌生成 CEK
  4. 红帽构建的 Keycloak 使用这个生成的 CEK 加密 ID 令牌
  5. 红帽构建的 Keycloak 使用客户端的公钥加密 CEK。
  6. 客户端使用其私钥解密这个加密的 CEK
  7. 客户端使用解密的 CEK 解密 ID 令牌。

客户端以外的方都可以解密 ID 令牌。

客户端必须将其公钥传递给红帽构建的 Keycloak。Red Hat build of Keycloak 支持从客户端提供的 URL 下载公钥。客户端必须根据 Json Web Keys (JWK) 规范提供公钥。

该流程是:

  1. 打开客户端的 Keys 选项卡。
  2. JWKS URL 切换到 ON。
  3. JWKS URL 文本框中输入客户端的公钥 URL。

密钥加密算法在 Json Web Algorithm (JWA) 规范中定义。Red Hat build of Keycloak 支持:

  • RSAES-PKCS1-v1_5(RSA1_5)
  • RSAES OAEP 使用默认参数(RSA-OAEP)
  • RSAES OAEP 256 使用 SHA-256 和 MFG1 (RSA-OAEP-256)

选择算法的步骤为:

  1. 打开客户端 的高级 选项卡。
  2. 打开 Fine Grain OpenID Connect Configuration
  3. ID Token Encryption Content Algorithm 下拉菜单中选择算法

13.1.3.3. OpenID Connect 兼容性模式

本节存在以便向后兼容。点每个字段的详情的问号图标。

启用 OAuth 2.0 通用 TLS 证书绑定访问令牌

双向 TLS 将访问令牌和刷新令牌与客户端证书绑定,该证书在 TLS 握手期间交换。这个绑定可防止攻击者使用 stolen 令牌。

这种类型的令牌是拥有者(key-of-key)令牌。与 bearer 令牌不同,令牌令牌的接收者可以验证令牌的发件人是否合法。

如果此设置为 on,工作流为:

  1. 令牌请求在授权代码流或混合流中发送到令牌端点。
  2. 红帽构建的 Keycloak 请求客户端证书。
  3. 红帽构建的 Keycloak 接收客户端证书。
  4. 红帽构建的 Keycloak 成功验证客户端证书。

如果验证失败,红帽构建的 Keycloak 会拒绝令牌。

在以下情况下,红帽构建的 Keycloak 将验证发送访问令牌或刷新令牌的客户端:

  • 令牌刷新请求发送到具有拥有者密钥刷新令牌端点。
  • UserInfo 请求发送到 UserInfo 端点,其具有持有者的访问令牌。
  • 注销请求发送到带有拥有者密钥刷新令牌的 Keycloak 专有 Logout 端点的非OIDC 兼容红帽构建。

如需了解更多详细信息,请参阅 OAuth 2.0 通用 TLS 客户端身份验证和证书绑定 访问令牌 中的 通用 TLS 客户端证书 Bound 访问令牌。

注意

Red Hat build of Keycloak 客户端适配器不支持 holder-of-key 令牌验证。Red Hat build of Keycloak 适配器将访问和刷新令牌视为 bearer 令牌。

应用层(DPoP)上的 OAuth 2.0 演示概念验证-Possession

DPoP 将访问令牌和客户端密钥对的公钥部分绑定在一起。这个绑定可防止攻击者使用 stolen 令牌。

这种类型的令牌是拥有者(key-of-key)令牌。与 bearer 令牌不同,令牌令牌的接收者可以验证令牌的发件人是否合法。

如果客户端请求中的客户端切换 Require Demonstrating proof of Possession (DPoP)标头 为 on,工作流为:

  1. 令牌请求在授权代码流或混合流中发送到令牌端点。
  2. 红帽构建的 Keycloak 请求了 DPoP 证明。
  3. 红帽构建的 Keycloak 接收 DPoP 证明。
  4. 红帽构建的 Keycloak 成功验证 DPoP 证明。

如果验证失败,红帽构建的 Keycloak 会拒绝令牌。

如果令牌请求中的交换机 需要演示概念验证(DPoP)标头,则客户端仍然可以在令牌请求 中发送 DPoP 证明。在这种情况下,红帽构建的 Keycloak 将验证 DPoP 证明,并将添加 thumbprint 到令牌。但是,如果交换机关闭,红帽为此客户端构建 Keycloak 服务器不会强制使用 DPoP 绑定。如果要确保特定的客户端始终使用 DPoP 绑定,则建议在 上进行这个切换。

在以下情况下,红帽构建的 Keycloak 将验证发送访问令牌或刷新令牌的客户端:

  • 令牌刷新请求发送到具有拥有者密钥刷新令牌端点。此验证仅对公共客户端完成,如 DPoP 规范中所述。对于机密客户端,不会通过适当的客户端凭据进行验证,以确保请求来自合法客户端。对于公共客户端,访问令牌和刷新令牌均受 DPoP 绑定。对于机密客户端,只有访问令牌绑定为 DPoP。
  • UserInfo 请求发送到 UserInfo 端点,其具有持有者的访问令牌。
  • 注销请求发送到带有持有者密钥刷新令牌的 Keycloak 专有退出端点 Logout 端点的 non-OIDC 红帽构建。此验证只针对公共客户端完成,如上所述。

如需了解更多详细信息,请参阅 OAuth 2.0 演示方式 Possession (DPoP)

注意

红帽构建的 Keycloak 客户端适配器不支持 DPoP 持有者令牌验证。Red Hat build of Keycloak 适配器将访问和刷新令牌视为 bearer 令牌。

注意

DPoP 是 技术预览,且不受支持。此功能默认为禁用。

使用-- features=preview or-- features=dpop启动服务器

OIDC 的高级设置

OpenID Connect 的高级设置允许您在客户端级别上为 会话和令牌超时 配置覆盖。

Advanced Settings

Expand
Configuration描述

访问令牌生命周期

该值会覆盖具有相同名称的 realm 选项。

客户端会话空闲

该值会覆盖具有相同名称的 realm 选项。该值应短于全局 SSO 会话空闲

客户端会话最大

该值会覆盖具有相同名称的 realm 选项。该值应短于全局 SSO 会话 Max

客户端离线会话空闲

此设置允许您为客户端配置较短的离线会话闲置超时。在红帽构建的 Keycloak 撤销其离线令牌前,超时是会话保持闲置的时间。如果没有设置,则使用 realm Offline Session Idle

客户端离线会话 Max

此设置允许您为客户端配置较短的离线会话 max 生命周期。生命周期span 是红帽构建的 Keycloak 撤销对应的离线令牌前的最长时间。这个选项需要在域中全局启用 离线会话 Max Limited,默认为 Offline Session Max

代码交换代码挑战方法的证明密钥

如果攻击者窃取合法客户端的授权代码,则代码交换(PKCE)的证明密钥会阻止攻击者获得适用于代码的令牌。

管理员可以选择以下选项之一:

(blank)
红帽构建的 Keycloak 不会应用 PKCE,除非客户端将适当的 PKCE 参数发送到红帽构建的 Keycloaks 授权端点。
S256
Red Hat build of Keycloak 适用于客户端 PKCE,其代码质询方法是 S256。
plain
Red Hat build of Keycloak 适用于客户端 PKCE,其代码质询方法是 plain。

如需了解更多详细信息,请参阅 OAuth 公共客户端的代码交换的 RFC 7636 概念验证

ACR 到级别身份验证(LoA)映射

在客户端的高级设置中,您可以定义哪个 身份验证方法类参考(ACR) 值映射到哪个 级别身份验证(LoA)。此映射也可以在域中指定,如 ACR 到 LoA Mapping 中所述。最佳实践是在域级别上配置此映射,它允许在多个客户端间共享相同的设置。

Default ACR 值 可用于在没有 acr _values 参数的情况下将登录请求发送到红帽构建的 Keycloak 时指定默认值,且没有附加了 acr_values 参数的 claims 参数。请参阅 官方 OIDC 动态客户端注册规格

警告

请注意,默认的 ACR 值用作默认级别,但无法可靠使用它来强制使用特定级别的登录。例如,假设您将 Default ACR 值 配置为 2 级。默认情况下,用户需要使用级别 2 进行身份验证。但是,当用户将参数明确附加到登录请求时,如 acr_values=1,则会使用级别 1。因此,如果客户端真正需要 2 级,则建议客户端检查 ID 令牌中是否存在 acr 声明,并仔细检查它包含请求的级别 2。要在红帽构建的 Keycloak 端实际强制使用特定的 ACR,请使用 Minimum ACR Value 设置。这使得管理员能够在无法验证令牌内请求的 acr 声明的应用程序上强制实施 ACR。

ACR to LoA mapping

详情请查看 步骤身份验证和 官方 OIDC 规格

13.1.4. 机密客户端凭证

如果客户端的客户端身份验证设置为 ON,必须在 Credentials 选项卡中配置客户端的凭证。???

credentials 标签页

Credentials Tab

Client Authenticator 下拉列表指定用于您的客户端的凭证类型。

客户端 ID 和 Secret

这个选择是默认设置。secret 自动生成。如果需要,点 Regenerate 以重新创建 secret。

签名的 JWT

Signed JWT

签名的 JWT 为 "Signed JSON Web Token"。

在此验证器中,您可以强制 客户端使用的 签名算法(任何算法默认有效)和 JWT 令牌允许的 Max expiration (在此周期后收到的令牌将被接受,因为它们太旧,请注意,在身份验证前需要发布令牌,默认为 60 秒)。

在选择此凭证类型时,还必须在密钥键中为客户端生成私钥和证书。私钥将用于为 JWT 签名,而证书供服务器用来验证签名。

keys 标签页

Keys tab

Generate new keys 按钮来启动此过程。

生成密钥

generate client keys

  1. 选择要使用的存档格式。
  2. 输入 密钥密码
  3. 输入 存储密码
  4. Generate

当您生成密钥时,红帽构建的 Keycloak 将存储证书,并为客户端下载私钥和证书。

您还可以使用外部工具生成密钥,然后通过单击 Import Certificate 来导入客户端的证书。

导入证书

Import Certificate

  1. 选择证书的存档格式。
  2. 输入存储密码。
  3. 单击 Import File,以选择证书文件。
  4. Import

如果您单击 Use JWKS URL,则不需要导入证书。在这种情况下,您可以提供以 JWK 格式发布公钥的 URL。使用这个选项时,如果更改了密钥,Red Hat build of Keycloak 会重新导入密钥。

如果您使用由红帽构建的 Keycloak 适配器保护的客户端,您可以使用这个格式配置 JWKS URL,假设 https://myhost.com/myapp 是客户端应用程序的根 URL:

https://myhost.com/myapp/k_jwks
Copy to Clipboard Toggle word wrap

如需了解更多详细信息,请参阅 服务器开发人员指南

使用客户端 Secret 签名 JWT

如果选择这个选项,您可以使用由客户端 secret 签名的 JWT,而不是私钥。

客户端机密将用于由客户端签署 JWT。

Signed JWT 验证器中所述,您可以为 JWT 令牌配置 签名算法Max expiration

X509 证书

红帽构建的 Keycloak 将验证客户端是否在 TLS Handshake 过程中使用正确的 X509 证书。

X509 证书

x509 client auth

验证器还使用配置的 regexp 验证表达式检查证书的 Subject DN 字段。在某些情况下,接受所有证书就足够了。在这种情况下,您可以使用 (React?) (?:$) 表达式。

红帽构建的 Keycloak 有两种方法从请求获取客户端 ID:

13.1.5. 客户端 Secret 轮转

重要

请注意,客户端 Secret 轮转支持正在开发中。实验性使用此功能。

对于具有 机密 客户端身份验证的客户端,红帽构建的 Keycloak 支持通过客户端 策略 轮转客户端 secret 的功能。

客户端 secret 轮转策略提供更高的安全性,以缓解所有问题,如 secret 泄漏。启用后,红帽构建的 Keycloak 支持每个客户端最多两个活跃的 secret。策略根据以下设置管理轮转:

  • Secret expiration: [seconds] - 当 secret 被轮转时,这是新 secret 的时间。添加到 secret 创建日期 中的数量(以秒为单位)。在策略执行时计算。
  • 轮转 secret 过期: [秒] - 当 secret 被轮转时,这个值是旧 secret 的剩余过期时间。这个值应该总是小于 Secret 过期。当值为 0 时,旧 secret 将在客户端轮转过程中立即删除。添加到 secret 轮转日期 中的数量(以秒为单位)。在策略执行时计算。
  • 其余的过期时间在更新期间进行轮转: [秒] - 当更新到动态客户端应该执行客户端 secret 轮转时的时间段。在策略执行时计算。

当发生客户端 secret 轮转时,会生成一个新的主 secret,旧客户端主 secret 将成为带有新过期日期的二级 secret。

13.1.5.1. 客户端 secret 轮转的规则

轮转不会自动或后台进程发生。要执行轮转,需要在客户端的凭证选项卡中或 Admin REST API 中通过红帽构建 Keycloak 管理控制台的 Red Hat build of Keycloak 管理控制台进行更新操作。在调用客户端更新操作时,会根据规则进行 secret 轮转:

  • Secret 过期的 值小于当前日期时。
  • 在动态客户端注册客户端更新请求过程中,如果 Remaining expiration time 的值与当前日期和 Secret 过期之间的周期匹配,客户端 secret 将自动轮转

此外,还可以通过 Admin REST API 强制客户端 secret 轮转。

注意

在创建新客户端期间,如果客户端 secret 轮转策略处于活动状态,则行为将自动应用。

警告

要将 secret 轮转行为应用到现有客户端,请在定义策略后更新该客户端,以便应用行为。

13.1.6. 创建 OIDC 客户端 Secret 轮转策略

以下是定义 secret 轮转策略的示例:

流程

  1. 单击菜单中的 Realm Settings
  2. Client Policies 选项卡。
  3. Profiles 页面上,单击 Create client profile

    创建配置集

    Create Client Profile

  4. Name 输入任何名称。
  5. 输入描述,帮助您识别配置集的用途 描述
  6. Save

    此操作会创建配置集,并可让您配置 executor。

  7. 单击 Add executor 以为这个配置集配置 executor。

    创建配置集执行器

    Client Profile Executor

  8. Executor Type 选择 secret-rotation
  9. Secret Expiration 输入每个 secret 的最大持续时间时间(以秒为单位)。
  10. Rotated Secret Expiration 输入每个轮转 secret 的最大持续时间时间(以秒为单位)。

    警告

    请记住,Rotated Secret Expiration 值必须始终小于 Secret Expiration

  11. 输入时间(以秒为单位),之后任何更新操作都会更新 Remain Expiration Time 的客户端。
  12. 点击 Add

    在上例中:

    • 每个 secret 在一周内都有效。
    • 轮转的 secret 会在两天后过期。
    • 更新动态客户端的窗口将在 secret 过期前一天启动。
  13. 返回到 Client Policies 选项卡。
  14. 单击 Policies
  15. Create client policy

    创建 Client Secret 轮转策略

    Client Rotation Policy

  16. Name 输入任何名称。
  17. 输入描述,帮助您识别 描述 的策略的用途。
  18. Save

    此操作会创建策略,并允许您将策略与配置集关联。它还允许您配置策略执行条件。

  19. 在 Conditions 下,单击 Add condition

    创建 Client Secret Rotation Policy Condition

    Client Rotation Policy Condition

  20. 要将行为应用到所有机密客户端,请在 Condition Type 字段中选择 client-access-type

    注意

    要应用到特定的客户端组,另一个方法是在 Condition Type 字段中选择 client-roles 类型。这样,您可以创建特定的角色,并为各个角色分配自定义轮转配置。

  21. 将机密 添加到 字段 Client Access Type
  22. 点击 Add
  23. 返回到策略设置,在 Client Profiles 下,单击 Add client profile,然后从列表中选择 Weekly Client Secret Rotation Profile,然后单击 Add

    客户端 Secret 轮转策略

    Client Rotation Policy

注意

要将 secret 轮转行为应用到现有客户端,请按照以下步骤执行:

使用管理控制台

  1. 点菜单中的 Clients
  2. 点客户端。
  3. Credentials 选项卡。
  4. 点客户端 secret 的 Re-generate

使用客户端 REST 服务,可通过两种方式执行:

  • 在客户端上通过更新操作
  • 通过重新生成客户端 secret 端点

13.1.7. 使用服务帐户

每个 OIDC 客户端都有一个内置 服务帐户。使用 此服务帐户 获取访问令牌。

流程

  1. 点菜单中的 Clients
  2. 选择您的客户端。
  3. Settings 选项卡。
  4. 客户端身份验证 切换为 On
  5. 选择 服务帐户角色
  6. 点击 Save
  7. 配置客户端凭据
  8. Scope 选项卡。
  9. 验证您是否具有角色,或将 Full Scope Allowed 切换到 ON
  10. Service Account Roles 选项卡
  11. 配置此服务帐户可供您的客户端使用的角色。

来自访问令牌的角色是以下部分:

  • 客户端的角色范围映射,以及从链接的客户端范围继承的角色范围映射。
  • 服务帐户角色。

要调用的 REST URL 是 /realms/{realm-name}/protocol/openid-connect/token。此 URL 必须作为 POST 请求调用,并且要求您使用请求发布客户端凭据。

默认情况下,客户端凭证由 Authorization: Basic 标头中的客户端的 clientId 和 clientSecret 表示,但您也可以使用签名 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
Copy to Clipboard Toggle word wrap

响应与 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
}
Copy to Clipboard Toggle word wrap

默认仅返回访问令牌。不会返回刷新令牌,默认情况下,在 Red Hat build of Keycloak 侧不会创建用户会话。由于缺少刷新令牌,访问令牌过期时需要重新进行身份验证。但是,这种情况并不表示红帽构建的 Keycloak 服务器的额外开销,因为默认情况下不会创建会话。

在这种情况下,不需要注销。但是,可以通过向 OAuth2 撤销端点发送请求来撤销发布的访问令牌,如 OpenID Connect Endpoints 部分所述。

13.1.8. 令牌中的角色映射

当用户验证时,有一些角色被添加到访问令牌中。默认情况下,Realm 角色添加到 访问令牌中的 realm_access 声明中。客户端角色 默认添加到 resource_access 声明中。

添加到令牌的角色是以下的交集:

13.1.8.1. 分配给用户的角色

分配给用户的角色可以在角色映射中定义,如 本节所述。几个详情:

  • 如果用户是某些组的成员,则也会应用这些组的所有角色。???
  • 如果角色是 复合角色,则也会应用复合角色的子角色。在令牌中,角色列表将扩展,并包含所有角色。
  • 如果经过身份验证的用户不是普通用户,但 代表客户端的服务帐户,则使用服务帐户角色。服务帐户角色在特定客户端 的服务帐户角色 中定义。

13.1.8.2. 角色协议映射器

与其他声明类似,角色被添加到由专用 协议 映射程序为客户端发布的访问令牌中。域中定义了 Built-in 客户端 范围角色。由于它是 Realm 默认客户端范围,因此默认定义为每个域 客户端的默认客户端范围。您可以通过查看 Client range 选项卡,然后查找 角色 客户端范围,在 admin 控制台中看到此客户端范围。默认情况下,此客户端范围包含这些协议映射器:

  • 协议映射 域角色 - 此协议映射器用于将 realm 角色添加到令牌声明中。默认情况下,配置类似如下:

realm roles mapper

mapper oidc realm roles

  • 协议映射器 客户端角色 - 此协议映射器用于将客户端角色添加到令牌声明中。默认情况下,配置类似如下:

客户端角色映射器

mapper oidc client roles

  • 协议映射器 使用者解析 - 此协议映射程序用于根据应用的客户端角色填写访问令牌中的 aud 声明。此映射器的详细信息位于 Audience 解析部分

如您在域角色和客户端角色映射器配置中看到的,可以配置:

  • 如果角色仅添加到访问令牌中,或者添加到其他令牌中,如 ID 令牌。默认情况下,角色添加到访问令牌和内省端点。
  • 添加角色的声明是什么。默认情况下,realm 角色添加到 realm_access 声明中。例如,包含 2 realm roles role1role2 的 JWT 令牌中的声明类似如下:

    "realm_access": {
      "roles": [ "role1", "role2" ]
    }
    Copy to Clipboard Toggle word wrap

    客户端角色默认添加到 resource_access 令牌声明中。这个声明将在令牌中类似,其中包含客户端帐户的 manage- account manage-account-links 客户端角色 target-client1-role 的 client target-client 1-role :

    "resource_access": {
      "target-client1": {
        "roles": [ "target-client1-role" ]
      },
      "account": {
        "roles": [ "manage-account", "manage-account-links" ]
      }
    }
    Copy to Clipboard Toggle word wrap

通过调整角色协议映射器的配置选项 声明名称,可以指定这些角色将在配置的声明中添加到令牌中。

如果您要为一个特定的客户端更新角色声明(例如,客户端 foo 需要声明 my-realm-roles 中的 realm 角色,而不是声明 realm_access),则可以从您的客户端中删除默认客户端范围角色,并在客户端 的专用客户端范围内配置 realm/client 协议映射器。

13.1.8.3. Example

Audience 文档 包含更详细的示例,它涵盖了有关角色映射以及添加到令牌中的 audience (Claim aud)的一些详细信息。另外,尝试 客户端范围评估来查看 在为特定客户端发布令牌时使用的有效范围、协议映射器和角色范围映射以及 JWT 令牌如何查找用户、客户端和应用客户端范围的特定组合时很有用。

13.1.9. 受众支持

通常,部署红帽构建的 Keycloak 环境由一组使用红帽构建的 Keycloak 进行身份验证 的机密公共 客户端应用程序组成。这些客户端是 前端客户端,它可以直接将用户重定向到红帽构建的 Keycloak,以请求浏览器身份验证。然后,特定客户端会在身份验证成功后接收一组令牌。

也提供 服务 ( OAuth 2 规范中的资源服务器 )服务,服务于来自客户端应用程序的请求并为这些应用提供资源。这些服务需要 访问令牌 (Bearer 令牌)从 frontend 应用或其他服务 发送到它们,以验证请求。

必须小心谨慎,以确保访问令牌具有有限的特权,并且服务无法使用特定的访问令牌来访问其他第三方服务。在服务间信任的环境中,您可能会遇到此示例场景:

  1. 前端客户端应用程序 frontend-client 需要针对红帽构建的 Keycloak 进行身份验证。
  2. 红帽构建的 Keycloak 验证用户身份。
  3. 红帽构建的 Keycloak 将令牌发布到应用程序 frontend-client
  4. frontend-client 应用使用令牌来调用 service1
  5. service1 服务将响应返回给应用。但是,假设该服务将尝试使用令牌,并保持它进一步使用。
  6. 然后,service1 使用之前发送到的 applications 令牌调用另一个服务 service2service2 不会检查不应用于调用令牌,它将为请求提供服务并返回成功响应。这会导致安全性中断,因为 service1 错误地使用令牌代表客户端应用程序 frontend-client 访问其他服务。

这种情境不太可能在服务间具有高度信任的环境,而不是在信任较低的环境中实现。

为防止访问令牌被滥用,访问令牌可以包含代表受众的声明 aud声明 通常应代表使用令牌的所有服务的客户端 ID。在服务间具有低信任的环境中,建议:

  • 限制令牌的使用者,以确保访问令牌仅包含有限数量的受众。
  • 配置您的服务以验证令牌的使用者。

要防止上面示例中的 service1 滥用令牌,流的安全变体可能类似如下:

  1. 前端应用程序 frontend-client 会根据红帽构建的 Keycloak 进行身份验证。
  2. 红帽构建的 Keycloak 验证用户身份。
  3. 红帽构建的 Keycloak 将令牌发布到 frontend-client 应用程序。frontend-client 知道需要调用 service1,以便在发送到红帽构建的 Keycloak 的身份验证请求中放置 scope=service1-scope。范围 service1-scope 是客户端 范围,管理员可能需要创建它。以下章节有一些 选项,如何设置这样的客户端范围。令牌声明类似如下:

    "aud": "service1"
    Copy to Clipboard Toggle word wrap

    这声明客户端可以使用此访问令牌来调用 service1

  4. frontend-client 应用使用令牌来调用 service1
  5. service1 为客户端应用程序 frontend-application 提供请求。但是,假设该服务将尝试使用令牌,并保持它进一步使用。
  6. 然后,service1 将尝试使用令牌调用 service2。调用不成功,因为 service2 服务检查令牌的使用者,并发现其 audience 仅适用于 service1。因此,service2 将拒绝请求,并将返回错误给 service1。这个行为是正常的,安全性不会出现问题。

13.1.9.1. 服务能够调用其他服务

在某些环境中,可能需要 service1service2 检索额外数据,以将数据返回到原始客户端应用 frontend-client。为了可以做到这一点,可能会有几个可能:

  • 确保向 frontend-client 发出的初始访问令牌将包含 service1service2 作为受众。假设设置了正确的客户端范围,frontend-client 可能使用 scope=service1-scope service2-scope 作为 scope 参数的值。然后,发布的令牌会包含如下 aud 声明:

    "aud": [ "service1", "service2" ]
    Copy to Clipboard Toggle word wrap

    这种访问令牌可用于调用 service1service2。因此,service1 将能够使用此类令牌成功调用 service2 来检索其他数据。

  • 之前在令牌受众中的两个服务允许 service1 调用 service2。但是,这意味着 frontend-client 也可以直接使用其访问令牌来调用 service2。在某些情况下可能不需要这样做。您可能希望 service1 能够调用 service2,但同时,您不希望 frontend-client 能够直接调用 service2。此类场景的解决方案可能是使用 Token 交换。在这种情况下,初始令牌仍只有 service1 作为 audience。但是,当令牌发送到 service1 后,service1 可能会发送 Token Exchange 请求,以交换另一个令牌的令牌,后者具有 service2 作为受众。有关如何使用 令牌交换的详细信息,请参阅令牌交换章节

13.1.9.2. 设置

在设置 audience 检查时:

  • 确保将服务配置为检查发送给它们的访问令牌的受众。这可以以特定于您的客户端 OIDC 适配器的方式完成,用于保护 OIDC 客户端应用程序。
  • 确保由红帽构建的 Keycloak 发布的访问令牌包含所有必要的受众。

    通过两种方式,可以将受众添加到令牌中:

13.1.9.3. 根据客户端角色自动添加使用者

Audience Resolve 协议映射器在默认客户端 范围角色 中定义。映射器检查至少有一个客户端角色用于当前令牌的客户端。然后,每个此类客户端的客户端 ID 被添加到 audience 中,如果您的服务客户端依赖客户端角色,这非常有用。服务客户端通常是在没有启用任何流的情况下的客户端,这些客户端可能没有直接向自身发出的任何令牌。它代表 OAuth 2 资源服务器

Token 角色映射部分包含 如何添加到令牌中的客户端角色。另请参阅以下示例。

13.1.9.3.1. 示例 - 令牌角色映射和受众声明

以下是如何使用客户端角色将 aud 声明添加到令牌中的示例步骤:

  1. 创建 OIDC 客户端 service1。可能为此客户端禁用 标准流 或任何其他流,因为它是服务客户端,这些客户端可能无法直接进行身份验证。如前文所述,可能的例外可能是 Standard Token Exchange switch。
  2. 前往该客户端的 Roles 选项卡,再创建客户端角色 service1-role
  3. 在同一域中创建用户 john,并向他分配上一步中创建的客户端 service1-role 的客户端 service 1-role。本节包含 一些有关如何进行操作的详细信息。
  4. 创建名为 service1-scope 的客户端范围。它可以通过 Include in token scope 标记为 ON。有关如何创建和设置新客户端范围的详情,请查看 本节
  5. 进入 service1-scope 的选项卡范围,并将客户端 service1-role 的角色 service 1-role 添加到 此客户端范围的 Role 范围映射
  6. 在域中创建另一个客户端 frontend-client
  7. 单击此客户端的 Client 范围,再选择第一个专用客户端范围 frontend-client-dedicated,然后进入选项卡 Scope 并禁用 Full scope 允许 开关
  8. 返回到此客户端的 Client 范围,再单击 Add client scope,并将 service1-scope 链接到 Optional。如需了解更多详细信息 ,请参阅客户端范围链接部分
  9. 单击 客户端范围 中的子选项卡 评估,如 本节所述。填写用户 john生成访问令牌 的子选项卡时,可以看到没有任何 aud 声明,因为生成的示例令牌中没有任何客户端角色。但是,当向 Scope 字段添加 scope service1-scope 时,可以看到客户端角色 service1-role 不在 service1- scope 的 Role 范围映射中,也包含在用户 john 的角色映射中。由于 aud 声明也将包含 service1

受众可以解决示例

audience resolving evaluate

如果您希望 service1 受众始终应用于向 frontend-client 客户端发布的令牌(不使用参数 scope=service1-scope),则您可以进行以下操作:

  • service1-scope 分配为 Default 客户端范围,而不是 可选
  • service1-role 的角色范围映射直接添加到 客户端的 Dedicated 客户端范围。在这种情况下,您不需要 service1-scope

请注意,由于这种方法基于客户端角色,因此它还要求用户自己(上例中的用户 john )是客户端 service1 的一些客户端角色的成员。否则,如果没有分配任何客户端角色,则不会包含 audience service1。如果您想包括使用者,无论客户端角色是什么,请参阅 硬编码 audience 部分。

注意

前端客户端本身不会自动添加到访问令牌 audience 中,因此允许在访问令牌和 ID 令牌之间轻松区分,因为访问令牌不包含作为 audience 发布令牌的客户端。

如果您需要客户端本身作为受众,请参阅 硬编码的 audience 选项。但是,不建议使用与 frontend 和 REST 服务相同的客户端。

13.1.9.4. 硬编码受众

当服务依赖于 realm 角色或根本不依赖于令牌中的角色时,使用硬编码的受众会很有用。硬编码受众是一个协议映射程序,它会将指定服务客户端的客户端 ID 添加为令牌的使用者。如果要使用与客户端 ID 不同的使用者,您可以使用任何自定义值,如 URL。

您可以将协议映射器直接添加到 frontend 客户端。如果直接添加了协议映射程序,则也会添加受众。

若要对协议映射器进行更多控制,您可以在专用客户端范围上创建协议映射程序,例如 service2

以下是硬编码受众的步骤示例

  1. 创建客户端 service2
  2. 创建客户端范围 service2-scope
  3. 在客户端范围的选项卡中,选择 配置新 映射程序 并选择 Audience
  4. 选择 Included Client Audience 作为 service2,并保存映射器

    受众协议映射器

    audience mapper

  5. 将新创建的客户端范围与某些客户端链接。例如,它可以作为 Optional 客户端范围链接到 上一示例 中创建的客户端 frontend-client
  6. 您可以选择为客户端范围被链接的客户端提供 Evaluate Client Scopes (如 frontend-client)并生成示例访问令牌。如果将 service2-scope 包含在 scope 参数中,则 audience service2 将添加到生成的访问令牌 的使用者 中,当您将其指定为可选的客户端范围时。

在机密客户端应用中,确保使用 scope 参数。当您要发出用于访问 service2 的令牌时,必须包含 scope=service2-scope 等值。

如果您的应用程序使用了带有所需值的 scope 参数,请参阅 Red Hat build of Keycloak JavaScript adapter 部分。

如果您希望在请求中包含 scope 参数,您可以将 service2-scope 链接为 Default 客户端范围,或使用配置此映射器的客户端专用范围。如果您要始终为 OIDC 客户端 frontend-client 的所有身份验证请求应用使用者,这很有用。

注意

默认情况下,AudienceAudience Resolve 协议映射器都会将 audiences 添加到访问令牌中。ID 令牌通常仅包含单个 audience (签发令牌的客户端 ID),这是 OpenID Connect 规格的要求。但是,访问令牌不一定具有客户端 ID,这是为其发布的令牌,除非 Audience 映射器添加了它。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat