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;
}
}
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
Copied!
Toggle word wrap
Toggle overflow
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;
}
}
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
Copied!
Toggle word wrap
Toggle overflow