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;
    }
}
Copy to Clipboard Toggle word wrap

此方法返回的 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: serviceRealm: 管理 )可帮助选择 tenant-servicetenant-manage 配置。
  • 检查 URL 查询参数。它的工作方式与标头用于选择租户配置的方式类似。

所有这些选项都可以使用 OIDC 服务 应用程序的 custom TenantResolverTenantConfigResolver 实现轻松实现。

但是,由于 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;
    }
}
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

Theme

© 2025 Red Hat