5.11. 动态租户配置解析
如果您需要为需要支持的不同租户进行更多动态配置,且不想与配置文件中的多个条目结束,您可以使用 io.quarkus.oidc.TenantConfigResolver。
此接口允许您在运行时动态创建租户配置:
package io.quarkus.it.keycloak;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.function.Supplier;
import io.smallrye.mutiny.Uni;
import io.quarkus.oidc.OidcRequestContext;
import io.quarkus.oidc.OidcTenantConfig;
import io.quarkus.oidc.TenantConfigResolver;
import io.vertx.ext.web.RoutingContext;
@ApplicationScoped
public class CustomTenantConfigResolver implements TenantConfigResolver {
@Override
public Uni<OidcTenantConfig> resolve(RoutingContext context, OidcRequestContext<OidcTenantConfig> requestContext) {
String path = context.request().path();
String[] parts = path.split("/");
if (parts.length == 0) {
//Resolve to default tenant configuration
return null;
}
if ("tenant-c".equals(parts[1])) {
// Do 'return requestContext.runBlocking(createTenantConfig());'
// if a blocking call is required to create a tenant config,
return Uni.createFromItem(createTenantConfig());
}
//Resolve to default tenant configuration
return null;
}
private Supplier<OidcTenantConfig> createTenantConfig() {
final OidcTenantConfig config = new OidcTenantConfig();
config.setTenantId("tenant-c");
config.setAuthServerUrl("http://localhost:8180/realms/tenant-c");
config.setClientId("multi-tenant-client");
OidcTenantConfig.Credentials credentials = new OidcTenantConfig.Credentials();
credentials.setSecret("my-secret");
config.setCredentials(credentials);
// Any other setting supported by the quarkus-oidc extension
return () -> config;
}
}
此方法返回的 OidcTenantConfig 与从 application.properties 解析 oidc 命名空间配置的方式相同。您可以使用 quarkus-oidc 扩展支持的任何设置来填充它。
如果动态租户解析器返回 null,则下一步会尝试 静态租户配置解析。
5.11.1. OIDC web-app 应用程序的租户解析 复制链接链接已复制到粘贴板!
解析 OIDC web-app 应用程序配置的最简单选项是按照 Default resolution 部分中描述的步骤进行操作。
如果默认解析策略不适用于应用程序设置,请尝试以下其中一个选项。
有几个选项可用于选择租户配置,这些配置应该用来保护 服务和 web-app OIDC 应用程序的当前 HTTP 请求,例如:
-
检查 URL 路径。例如,
tenant-service配置必须用于/service路径,而tenant-manage配置必须用于/management路径。 -
检查 HTTP 标头。例如,如果 URL 路径始终为
/service,一个标头(如Realm: service或Realm: 管理)可帮助选择tenant-service和tenant-manage配置。 - 检查 URL 查询参数。它的工作方式与标头用于选择租户配置的方式类似。
所有这些选项都可以使用 OIDC 服务 应用程序的 custom TenantResolver 和 TenantConfigResolver 实现轻松实现。
但是,由于 HTTP 重定向需要完成 OIDC web-app 应用程序的代码身份验证流,可能需要自定义 HTTP cookie 以在此重定向请求前后选择相同的租户配置,因为:
- 如果在 OIDC 供应商中注册了单个重定向 URL,在重定向请求后 URL 路径可能不同。在租户配置解决后,可以恢复原始请求路径。
- 重定向后,原始请求中使用的 HTTP 标头不可用。
- 自定义 URL 查询参数在重定向后恢复,但仅在租户配置解决后恢复。
其中一个选项是确保解析 web-app 应用程序的租户配置的信息在重定向之前和之后可用,例如:
package org.acme.quickstart.oidc;
import java.util.List;
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.oidc.TenantResolver;
import io.vertx.core.http.Cookie;
import io.vertx.ext.web.RoutingContext;
@ApplicationScoped
public class CustomTenantResolver implements TenantResolver {
@Override
public String resolve(RoutingContext context) {
List<String> tenantIdQuery = context.queryParam("tenantId");
if (!tenantIdQuery.isEmpty()) {
String tenantId = tenantIdQuery.get(0);
context.response().addCookie(Cookie.cookie("tenant", tenantId));
return tenantId;
} else if (!context.request().cookies("tenant").isEmpty()) {
return context.request().getCookie("tenant").getValue();
}
return null;
}
}