5.10. 租户解析
5.10.1. 租户解析顺序 复制链接链接已复制到粘贴板!
OIDC 租户按照以下顺序解决:
-
如果主动身份验证被禁用,则首先检查
io.quarkus.oidc.Tenant注解。 -
使用自定义
TenantConfigResolver的动态租户解析。 -
使用其中一个选项进行静态租户解析: custom
TenantResolver、配置的租户路径和默认到最后一个请求路径片段作为租户 ID。
最后,如果在前面的步骤后没有解析租户 ID,则会选择默认的 OIDC 租户。
如需更多信息,请参阅以下部分:
另外,对于 OIDC web-app 应用程序,状态和会话 Cookie 还提供有关在授权代码流启动时使用上述选项之一解析的租户提示。如需更多信息,请参阅 OIDC web-app 应用程序的租户解析 部分。
5.10.2. 使用注解解析 复制链接链接已复制到粘贴板!
您可以使用 io.quarkus.oidc.Tenant 注解来解析租户标识符,作为使用 io.quarkus.oidc.TenantResolver 的替代选择。
必须禁用主动 HTTP 身份验证(quarkus.http.auth.proactive=false)才能使它正常工作。如需更多信息,请参阅 主动身份验证 指南。
假设应用程序支持两个 OIDC 租户( hr 和 default 租户),所有带 @Tenant ("hr") 的资源方法和类都通过使用 quarkus.oidc.hr.auth-server-url 配置的 OIDC 供应商进行身份验证。相反,所有其他类和方法仍然通过使用默认 OIDC 供应商进行身份验证。
- 1
io.quarkus.oidc.Tenant注解必须放在资源类或资源方法上。
在上例中,使用 @Authenticated 注释强制执行 sayHello 端点的身份验证。
或者,如果您使用 HTTP 安全策略 来保护端点,然后是 @Tenant 注解,您必须延迟此策略的权限检查,如下例所示:
quarkus.http.auth.permission.authenticated.paths=/api/hello quarkus.http.auth.permission.authenticated.methods=GET quarkus.http.auth.permission.authenticated.policy=authenticated quarkus.http.auth.permission.authenticated.applies-to=JAXRS
quarkus.http.auth.permission.authenticated.paths=/api/hello
quarkus.http.auth.permission.authenticated.methods=GET
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.http.auth.permission.authenticated.applies-to=JAXRS
- 1
- 告诉 Quarkus 在选择了
@Tenant注解后运行 HTTP 权限检查。
io.quarkus.oidc.Tenant 注解可用于为 WebSockets Next server 端点选择租户。该注解必须放在端点类上,因为在 HTTP 连接升级到 WebSocket 连接之前创建 SecurityIdentity。有关 HTTP 升级安全性的更多信息,请参阅 Quarkus "WebSockets Next reference" 指南中的 Secure HTTP 升级 部分。
5.10.3. 动态租户配置解析 复制链接链接已复制到粘贴板!
如果您需要为需要支持的不同租户进行更多动态配置,且不想与配置文件中的多个条目结束,您可以使用 io.quarkus.oidc.TenantConfigResolver。
此接口允许您在运行时动态创建租户配置:
此方法返回的 OidcTenantConfig 与从 application.properties 解析 oidc 命名空间配置的方式相同。您可以使用 quarkus-oidc 扩展支持的任何设置来填充它。
如果动态租户解析器返回 null,则下一步会尝试 静态租户配置解析。
5.10.3.1. 更新已解析的动态租户配置 复制链接链接已复制到粘贴板!
可能需要更新已解析的租户配置。例如,客户端 secret 可能需要根据注册的 OIDC 应用程序中的客户端 secret 更新来更新。
要更新配置,请使用 OidcTenantConfigBuilder 创建 OidcTenantConfig 的新实例,并根据需要进行修改,然后再返回它:
这一切都是要更新已解析的动态租户器配置,而无需重新连接到提供程序。
如果需要重新连接,例如,UserInfo 端点地址可能已更改为重新发现它,只需将 RoutingContext replace-tenant-configuration-context 属性设置为 true :
- 1
- 替换已解析的租户配置并重新连接到供应商
最后,如果您决定在现有 OIDC 会话仍然活跃时更新 resoved 配置,您可以移除会话 Cookie,用户重新验证以与最新的租户配置要求保持一致。如果需要,将 RoutingContext remove-session-cookie 属性设置为 true :
- 1
- 更新租户配置,删除会话 Cookie 和 triger 用户重新身份验证。如果可能,最好先获取用户登录,而不是在租户解析时触发重新身份验证。
5.10.4. 静态租户配置解析 复制链接链接已复制到粘贴板!
当您在 application.properties 文件中设置多个租户配置时,您只需要指定租户标识符的解析方式。要配置租户标识符的解析,请使用以下选项之一:
这些租户解析选项会按照列出的顺序尝试,直到租户 id 被解决为止。如果租户 id 仍然未解析(null),则会选择默认(未命名)租户配置。
5.10.4.1. 使用 TenantResolver解析 复制链接链接已复制到粘贴板!
以下 application.properties 示例演示了如何使用 TenantResolver 方法解析名为 a 和 b 的两个租户的租户标识符:
您可以从 io.quarkus.oidc.TenantResolver 返回 a 或 b 的租户 ID:
在本例中,最后一个请求路径片段的值是一个租户 id,但如果需要,您可以实施更复杂的租户标识符解析逻辑。
5.10.4.2. 配置租户路径 复制链接链接已复制到粘贴板!
您可以使用 quarkus.oidc.tenant-paths 配置属性来解析租户标识符,作为使用 io.quarkus.oidc.TenantResolver 的替代选择。以下是如何为上例中使用的 HelloResource 资源的 sayHello 端点选择 hr 租户:
quarkus.oidc.hr.tenant-paths=/api/hello quarkus.oidc.a.tenant-paths=/api/* quarkus.oidc.b.tenant-paths=/*/hello
quarkus.oidc.hr.tenant-paths=/api/hello
quarkus.oidc.a.tenant-paths=/api/*
quarkus.oidc.b.tenant-paths=/*/hello
路径匹配机制与 使用 配置 的授权完全相同。
5.10.4.3. 使用请求路径片段查找租户 ID 复制链接链接已复制到粘贴板!
租户标识符的默认解析基于惯例,身份验证请求必须将租户标识符包含在请求路径的一个路径片段中。
以下 application.properties 示例演示了如何配置名为 google 和 github 的两个租户:
在提供的示例中,两个租户都将 OIDC web-app 应用程序配置为使用授权代码流来验证用户,并在身份验证后生成会话 Cookie。在 Google 或 GitHub 验证当前用户后,用户将返回到经过身份验证的用户的 /signed-in 区域,如 JAX-RS 端点上的安全资源路径。
最后,要完成默认租户解析,请设置以下配置属性:
quarkus.http.auth.permission.login.paths=/google,/github quarkus.http.auth.permission.login.policy=authenticated
quarkus.http.auth.permission.login.paths=/google,/github
quarkus.http.auth.permission.login.policy=authenticated
如果端点在 http://localhost:8080 上运行,您也可以为用户提供登录到 http://localhost:8080/google 或 http://localhost:8080/github 的 UI 选项,而无需添加特定的 /google 或 /github JAX-RS 资源路径。
身份验证完成后,租户标识符也会记录在会话 Cookie 名称中。因此,经过身份验证的用户可以访问安全应用程序区域,而无需将 google 或 github 路径值包含在安全 URL 中。
默认解析也可以用于 Bearer 令牌身份验证。仍然可能不太实际,因为租户标识符必须始终设置为最后一个路径片段值。
5.10.4.4. 使用令牌签发者声明解析租户 复制链接链接已复制到粘贴板!
支持 Bearer 令牌身份验证的 OIDC 租户可以使用访问令牌的签发者解决。对于基于签发者的解析功能可以正常工作,必须满足以下条件:
-
访问令牌必须采用 JWT 格式,并且包含签发者(
is)令牌声明。 -
只有带有应用程序类型
服务或混合的OIDC 租户才被考虑。这些租户必须发现或配置了令牌签发者。
基于签发者的解析通过 quarkus.oidc.resolve-tenants-with-issuer 属性启用。例如:
5.10.5. OIDC web-app 应用程序的租户解析 复制链接链接已复制到粘贴板!
OIDC web-app 应用程序的租户解析必须在授权代码流中至少 3 次进行,当 OIDC 租户特定配置会影响以下步骤的运行方式。
第 1 步:未验证的用户访问端点,并重定向到 OIDC 供应商
当未经身份验证的用户访问安全路径时,用户会被重定向到 OIDC 供应商以进行身份验证,并且使用租户配置来构建重定向 URI。
静态租户 配置 解析部分中列出的所有 静态和动态租户解析 选项都可用于解析租户。
第 2 步:用户重定向到端点
在提供程序身份验证后,用户会被重定向到 Quarkus 端点,租户配置用于完成授权代码流。
静态租户 配置 解析部分中列出的所有 静态和动态租户解析 选项都可用于解析租户。在租户解析开始前,授权代码流状态 cookie 用于将已解析的租户配置 id 设置为 RoutingContext tenant-id 属性:自定义 dynamic TenantConfigResolver 和 static TenantResolver 租户解析器都可以检查它。
第 3 步:经过身份验证的用户使用会话 Cookie 访问安全路径
租户配置决定了会话 Cookie 如何验证和刷新。在租户解析开始前,授权代码流 会话 Cookie 用于将已解析的租户配置 id 设为 RoutingContext tenant-id 属性:自定义 dynamic TenantConfigResolver 和 static TenantResolver 租户解析器都可以检查它。
例如,以下是自定义 TenantConfigResolver 如何避免创建已解析的租户配置,否则可能需要阻止对数据库或其他远程源的读取:
默认配置可能类似如下:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/default quarkus.oidc.client-id=client-default quarkus.oidc.credentials.secret=secret-default quarkus.oidc.application-type=web-app
quarkus.oidc.auth-server-url=http://localhost:8180/realms/default
quarkus.oidc.client-id=client-default
quarkus.oidc.credentials.secret=secret-default
quarkus.oidc.application-type=web-app
上例假定 tenant-a、tenant-b 和默认租户都用于保护同一端点路径。换句话说,在用户通过 租户 配置进行身份验证后,此用户将无法选择在此用户注销前与 tenant-b 或默认配置进行身份验证,并有会话 Cookie 清除或过期。
多个 OIDC web-app 租户可以保护特定于租户的路径的情况不太常见,而且还需要额外关注。当多个 OIDC web-app 租户(如 tenant-a、tenant-b 和默认租户)用于控制对租户特定路径的访问时,使用一个 OIDC 供应商进行身份验证的用户必须能够访问需要与另一个供应商进行身份验证的路径,否则可能会导致意外的身份验证失败。例如,如果 tenant-a 身份验证需要 Keycloak 身份验证,并且 tenant-b 身份验证需要 Auth0 身份验证 ,那么如果租户 验证的用户试图访问由 tenant-b 配置保护的路径,则不会验证会话 Cookie,因为 Auth0 公钥无法验证由 Keycloak 签名的令牌。避免多个 web-app 租户冲突的一个简单方法是设置特定于租户的会话路径,如下例所示:
默认租户配置应调整如下:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/default quarkus.oidc.client-id=client-default quarkus.oidc.credentials.secret=secret-default quarkus.oidc.authentication.cookie-path=/default quarkus.oidc.application-type=web-app
quarkus.oidc.auth-server-url=http://localhost:8180/realms/default
quarkus.oidc.client-id=client-default
quarkus.oidc.credentials.secret=secret-default
quarkus.oidc.authentication.cookie-path=/default
quarkus.oidc.application-type=web-app
当多个 OIDC web-app 租户保护租户保护租户时,不建议使用同一会话 Cookie 路径,并应避免它,因为它需要更关注自定义解析器,例如: