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;
}
}