5.6. 配置应用程序
# Default tenant configuration %prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.oidc.client-id=multi-tenant-client quarkus.oidc.credentials.secret=secret quarkus.oidc.application-type=web-app # Tenant A configuration is created dynamically in CustomTenantConfigResolver # HTTP security configuration quarkus.http.auth.permission.authenticated.paths=/* quarkus.http.auth.permission.authenticated.policy=authenticated
第一个配置是默认租户配置,应在无法从请求中推断租户时使用。请注意,%prod
配置集前缀与 quarkus.oidc.auth-server-url
一起使用,以支持使用 Dev Services for Keycloak 测试多租户应用程序。此配置使用 Keycloak 实例来验证用户。
当传入请求映射到 tenant-a
租户时,会使用由 TenantConfigResolver
提供的第二个配置。
这两个配置都会映射到同一 Keycloak 服务器实例,同时使用 不同的域
。
或者,您可以在 application.properties
中直接配置 tenant-a
:
# Default tenant configuration %prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.oidc.client-id=multi-tenant-client quarkus.oidc.credentials.secret=secret quarkus.oidc.application-type=web-app # Tenant A configuration quarkus.oidc.tenant-a.auth-server-url=http://localhost:8180/realms/tenant-a quarkus.oidc.tenant-a.client-id=multi-tenant-client quarkus.oidc.tenant-a.credentials.secret=secret quarkus.oidc.tenant-a.application-type=web-app # HTTP security configuration quarkus.http.auth.permission.authenticated.paths=/* quarkus.http.auth.permission.authenticated.policy=authenticated
在这种情况下,也使用自定义 TenantConfigResolver
来解析它:
package org.acme.quickstart.oidc; import jakarta.enterprise.context.ApplicationScoped; import io.quarkus.oidc.TenantResolver; import io.vertx.ext.web.RoutingContext; @ApplicationScoped public class CustomTenantResolver implements TenantResolver { @Override public String resolve(RoutingContext context) { String path = context.request().path(); String[] parts = path.split("/"); if (parts.length == 0) { //Resolve to default tenant configuration return null; } return parts[1]; } }
您可以在 配置文件中定义多个租户。要在从 TenantResolver
实现解析租户时正确映射它们,请确保每个租户都有唯一的别名。
但是,使用静态租户解析(涉及在 application.properties
中配置租户)并使用 TenantResolver
解析它们以使用 Keycloak 的 Dev Services 测试端点,因为它不知道请求如何映射到单独的租户,且无法动态提供租户特定的 quarkus.oidc.<tenant-id>.auth-server-url
值。因此,在 application.properties
中使用 %prod
前缀和特定于租户的 URL 都无法在测试和开发模式下工作。
当当前租户代表 OIDC web-app
应用程序时,当前的 io.vertx.ext.web.RoutingContext
包含 tenant-id
属性,只要为完成代码身份验证流的所有请求以及已验证的、已验证的状态或会话 Cookie 都会调用 tenant-id 属性。因此,在使用多个 OIDC 供应商时,您只需要特定于路径的检查来解析租户 ID (如果 RoutingContext
没有设置 tenant-id
属性),例如:
package org.acme.quickstart.oidc; import jakarta.enterprise.context.ApplicationScoped; import io.quarkus.oidc.TenantResolver; import io.vertx.ext.web.RoutingContext; @ApplicationScoped public class CustomTenantResolver implements TenantResolver { @Override public String resolve(RoutingContext context) { String tenantId = context.get("tenant-id"); if (tenantId != null) { return tenantId; } else { // Initial login request String path = context.request().path(); String[] parts = path.split("/"); if (parts.length == 0) { //Resolve to default tenant configuration return null; } return parts[1]; } } }
如果没有注册自定义 TenantResolver
,这是 Quarkus OIDC 如何解析静态自定义租户。
类似的技术可与 TenantConfigResolver
一起使用,其中上下文中提供的 tenant-id
可以返回 OidcTenantConfig
已在上一个请求中准备。
如果您也 使用带有 Panache 多租户的 Hibernate ORM 多租户 或 MongoDB,并且租户 ID 相同,且必须从 Vert.x RoutingContext
中提取,您可以从 OIDC Tenant Resolver 将租户 ID 传给 Hibernate ORM Tenant Resolver 或带有 Panache Mongo Database Resolver 作为 RoutingContext
属性的 MongoDB,例如:
public class CustomTenantResolver implements TenantResolver { @Override public String resolve(RoutingContext context) { String tenantId = extractTenantId(context); context.put("tenantId", tenantId); return tenantId; } }