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
namespace 設定を解析するために使用されるものと同じです。quarkus-oidc
エクステンションでサポートされている任意の設定を使用して、これを入力できます。
動的テナントリゾルバーが null
を返す場合は、次に 静的テナント設定の解決 が試行されます。
5.11.1. OIDC web-app アプリケーションのテナント解決
OIDC web-app
アプリケーション設定を解決する最も簡単なオプションは、デフォルトの解決 セクションで説明されている手順に従うことです。
デフォルトの解像度ストラテジーがアプリケーション設定で機能しない場合は、以下のいずれかのオプションを試してください。
service
および web-app
の両方の OIDC アプリケーションに対する現在の HTTP 要求を保護するために使用するテナント設定を選択するには、次のようないくつかのオプションがあります。
-
URL パスを確認してください。たとえば、
/service
パスにはtenant-service
設定を使用し、/management
パスにはtenant-manage
設定を使用する必要があります。 -
HTTP ヘッダーを確認してください。たとえば、URL パスが常に
/service
である場合、Realm: service
、Realm: management
などのヘッダーを使用すると、tenant-service
設定とtenant-manage
設定を選択できます。 - URL クエリーパラメーターを確認してください。これは、ヘッダーを使用してテナント設定を選択する方法と同様に機能します。
これらのオプションはすべて、OIDC service
アプリケーションのカスタム TenantResolver
および TenantConfigResolver
実装を使用して簡単に実装できます。
ただし、OIDC web-app
アプリケーションのコード認証フローを完了するには HTTP リダイレクトが必要なため、このリダイレクト要求の前後で同じテナント設定を選択するには、カスタム HTTP Cookie が必要になる場合があります。その理由は次のとおりです。
- OIDC プロバイダーに単一のリダイレクト URL が登録されている場合は、リダイレクト要求後の URL パスが同じではない可能性があります。テナント設定が解決された後、元のリクエストパスを復元できます。
- 元のリクエスト中に使用された HTTP ヘッダーは、リダイレクト後に使用できなくなります。
- カスタム URL クエリーパラメーターはリダイレクト後に復元されますが、テナント設定が解決された後にのみ復元されます。
リダイレクトの前後で web-app
アプリケーションのテナント設定を解決するための情報が利用できるようにする 1 つのオプションは、Cookie を使用することです。次に例を示します。
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; } }