Skip to content

Commit

Permalink
feat(oidc): Add tenant config builder
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Dec 1, 2024
1 parent 2d19846 commit bb052ce
Show file tree
Hide file tree
Showing 38 changed files with 5,732 additions and 704 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,16 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
private OidcTenantConfig createTenantConfig(String tenantId, RegisteredClient client) {
ClientMetadata metadata = client.getMetadata();
OidcTenantConfig oidcConfig = new OidcTenantConfig();
oidcConfig.setTenantId(tenantId);
oidcConfig.setAuthServerUrl(authServerUrl);
oidcConfig.setApplicationType(ApplicationType.WEB_APP);
oidcConfig.setClientName(metadata.getClientName());
oidcConfig.setClientId(metadata.getClientId());
oidcConfig.getCredentials().setSecret(metadata.getClientSecret());
String redirectUri = metadata.getRedirectUris().get(0);
oidcConfig.getAuthentication().setRedirectPath(URI.create(redirectUri).getPath());
String redirectPath = URI.create(metadata.getRedirectUris().get(0)).getPath();
OidcTenantConfig oidcConfig = OidcTenantConfig
.authServerUrl(authServerUrl)
.tenantId(tenantId)
.applicationType(ApplicationType.WEB_APP)
.clientName(metadata.getClientName())
.clientId(metadata.getClientId())
.credentials(metadata.getClientSecret())
.authentication().redirectPath(redirectPath).end()
.build();
return oidcConfig;
}
}
Expand Down Expand Up @@ -208,15 +209,16 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
// Create metadata of registered clients to OidcTenantConfig
private OidcTenantConfig createTenantConfig(String tenantId, ClientMetadata metadata) {
OidcTenantConfig oidcConfig = new OidcTenantConfig();
oidcConfig.setTenantId(tenantId);
oidcConfig.setAuthServerUrl(authServerUrl);
oidcConfig.setApplicationType(ApplicationType.WEB_APP);
oidcConfig.setClientName(metadata.getClientName());
oidcConfig.setClientId(metadata.getClientId());
oidcConfig.getCredentials().setSecret(metadata.getClientSecret());
String redirectUri = metadata.getRedirectUris().get(0);
oidcConfig.getAuthentication().setRedirectPath(URI.create(redirectUri).getPath());
String redirectPath = URI.create(metadata.getRedirectUris().get(0)).getPath();
OidcTenantConfig oidcConfig = OidcTenantConfig
.authServerUrl(authServerUrl)
.tenantId(tenantId)
.applicationType(ApplicationType.WEB_APP)
.clientName(metadata.getClientName())
.clientId(metadata.getClientId())
.credentials(metadata.getClientSecret())
.authentication().redirectPath(redirectPath).end()
.build();
return oidcConfig;
}
Expand Down Expand Up @@ -287,15 +289,16 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
// Create metadata of registered clients to OidcTenantConfig
private OidcTenantConfig createTenantConfig(String tenantId, ClientMetadata metadata) {
OidcTenantConfig oidcConfig = new OidcTenantConfig();
oidcConfig.setTenantId(tenantId);
oidcConfig.setAuthServerUrl(authServerUrl);
oidcConfig.setApplicationType(ApplicationType.WEB_APP);
oidcConfig.setClientName(metadata.getClientName());
oidcConfig.setClientId(metadata.getClientId());
oidcConfig.getCredentials().setSecret(metadata.getClientSecret());
String redirectUri = metadata.getRedirectUris().get(0);
oidcConfig.getAuthentication().setRedirectPath(URI.create(redirectUri).getPath());
String redirectPath = URI.create(metadata.getRedirectUris().get(0)).getPath();
OidcTenantConfig oidcConfig = OidcTenantConfig
.authServerUrl(authServerUrl)
.tenantId(tenantId)
.applicationType(ApplicationType.WEB_APP)
.clientName(metadata.getClientName())
.clientId(metadata.getClientId())
.credentials(metadata.getClientSecret())
.authentication().redirectPath(redirectPath).end()
.build();
return oidcConfig;
}
Expand Down Expand Up @@ -367,15 +370,16 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
private OidcTenantConfig createTenantConfig(String tenantId, RegisteredClient client) {
ClientMetadata metadata = client.getMetadata();
OidcTenantConfig oidcConfig = new OidcTenantConfig();
oidcConfig.setTenantId(tenantId);
oidcConfig.setAuthServerUrl(authServerUrl);
oidcConfig.setApplicationType(ApplicationType.WEB_APP);
oidcConfig.setClientName(metadata.getClientName());
oidcConfig.setClientId(metadata.getClientId());
oidcConfig.getCredentials().setSecret(metadata.getClientSecret());
String redirectUri = metadata.getRedirectUris().get(0);
oidcConfig.getAuthentication().setRedirectPath(URI.create(redirectUri).getPath());
String redirectPath = URI.create(metadata.getRedirectUris().get(0)).getPath();
OidcTenantConfig oidcConfig = OidcTenantConfig
.authServerUrl(authServerUrl)
.tenantId(tenantId)
.applicationType(ApplicationType.WEB_APP)
.clientName(metadata.getClientName())
.clientId(metadata.getClientId())
.credentials(metadata.getClientSecret())
.authentication().redirectPath(redirectPath).end()
.build();
return oidcConfig;
}
}
Expand Down Expand Up @@ -477,15 +481,16 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
private OidcTenantConfig createTenantConfig(String tenantId, RegisteredClient client) {
ClientMetadata metadata = client.getMetadata();
OidcTenantConfig oidcConfig = new OidcTenantConfig();
oidcConfig.setTenantId(tenantId);
oidcConfig.setAuthServerUrl(authServerUrl);
oidcConfig.setApplicationType(ApplicationType.WEB_APP);
oidcConfig.setClientName(metadata.getClientName());
oidcConfig.setClientId(metadata.getClientId());
oidcConfig.getCredentials().setSecret(metadata.getClientSecret());
String redirectUri = metadata.getRedirectUris().get(0);
oidcConfig.getAuthentication().setRedirectPath(URI.create(redirectUri).getPath());
String redirectPath = URI.create(metadata.getRedirectUris().get(0)).getPath();
OidcTenantConfig oidcConfig = OidcTenantConfig
.authServerUrl(authServerUrl)
.tenantId(tenantId)
.applicationType(ApplicationType.WEB_APP)
.clientName(metadata.getClientName())
.clientId(metadata.getClientId())
.credentials(metadata.getClientSecret())
.authentication().redirectPath(redirectPath).end()
.build();
return oidcConfig;
}
}
Expand Down
70 changes: 35 additions & 35 deletions docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,13 @@ public class CustomTenantResolver implements TenantConfigResolver {
if (path.startsWith("/tenant-a")) {
String keycloakUrl = ConfigProvider.getConfig().getValue("keycloak.url", String.class);
OidcTenantConfig config = new OidcTenantConfig();
config.setTenantId("tenant-a");
config.setAuthServerUrl(keycloakUrl + "/realms/tenant-a");
config.setClientId("multi-tenant-client");
config.getCredentials().setSecret("secret");
config.setApplicationType(ApplicationType.HYBRID);
OidcTenantConfig config = OidcTenantConfig
.authServerUrl(keycloakUrl + "/realms/tenant-a")
.tenantId("tenant-a")
.clientId("multi-tenant-client")
.credentials("secret")
.applicationType(ApplicationType.HYBRID)
.build();
return Uni.createFrom().item(config);
} else {
// resolve to default tenant config
Expand Down Expand Up @@ -707,16 +708,12 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
}
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);
final OidcTenantConfig config = OidcTenantConfig
.authServerUrl("http://localhost:8180/realms/tenant-c")
.tenantId("tenant-c")
.clientId("multi-tenant-client")
.credentials("my-secret")
.build();
// Any other setting supported by the quarkus-oidc extension
Expand Down Expand Up @@ -935,12 +932,13 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
}
private OidcTenantConfig createTenantConfig(String tenantId, String clientId, String secret) {
final OidcTenantConfig config = new OidcTenantConfig();
config.setTenantId(tenantId);
config.setAuthServerUrl("http://localhost:8180/realms/" + tenantId);
config.setClientId(clientId);
config.getCredentials().setSecret(secret);
config.setApplicationType(ApplicationType.WEB_APP);
final OidcTenantConfig config = OidcTenantConfig
.authServerUrl("http://localhost:8180/realms/" + tenantId)
.tenantId(tenantId)
.clientId(clientId)
.credentials(secret)
.applicationType(ApplicationType.WEB_APP)
.build();
return config;
}
}
Expand Down Expand Up @@ -1000,13 +998,14 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
}
private OidcTenantConfig createTenantConfig(String tenantId, String cookiePath, String clientId, String secret) {
final OidcTenantConfig config = new OidcTenantConfig();
config.setTenantId(tenantId);
config.setAuthServerUrl("http://localhost:8180/realms/" + tenantId);
config.setClientId(clientId);
config.getCredentials().setSecret(secret);
config.setApplicationType(ApplicationType.WEB_APP);
config.getAuthentication().setCookiePath(cookiePath); <3>
final OidcTenantConfig config = OidcTenantConfig
.authServerUrl("http://localhost:8180/realms/" + tenantId)
.tenantId(tenantId)
.clientId(clientId)
.credentials(secret)
.applicationType(ApplicationType.WEB_APP)
.authentication().cookiePath(cookiePath).end() <3>
.build();
return config;
}
}
Expand Down Expand Up @@ -1078,12 +1077,13 @@ public class CustomTenantConfigResolver implements TenantConfigResolver {
}
private OidcTenantConfig createTenantConfig(String tenantId, String clientId, String secret) {
final OidcTenantConfig config = new OidcTenantConfig();
config.setTenantId(tenantId);
config.setAuthServerUrl("http://localhost:8180/realms/" + tenantId);
config.setClientId(clientId);
config.getCredentials().setSecret(secret);
config.setApplicationType(ApplicationType.WEB_APP);
final OidcTenantConfig config = OidcTenantConfig
.authServerUrl("http://localhost:8180/realms/" + tenantId)
.tenantId(tenantId)
.clientId(clientId)
.credentials(secret)
.applicationType(ApplicationType.WEB_APP)
.build();
return config;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import io.quarkus.oidc.common.runtime.OidcTlsSupport;
import io.quarkus.oidc.runtime.BlockingTaskRunner;
import io.quarkus.oidc.runtime.OidcConfig;
import io.quarkus.oidc.runtime.OidcUtils;
import io.quarkus.security.spi.runtime.BlockingSecurityExecutor;
import io.quarkus.tls.TlsConfigurationRegistry;
import io.quarkus.vertx.http.runtime.HttpConfiguration;
Expand Down Expand Up @@ -49,7 +48,7 @@ public class DefaultPolicyEnforcerResolver implements PolicyEnforcerResolver {
this.tlsSupport = OidcTlsSupport.empty();
}

var defaultTenantConfig = new OidcTenantConfig(OidcConfig.getDefaultTenant(oidcConfig), OidcUtils.DEFAULT_TENANT_ID);
var defaultTenantConfig = OidcConfig.getDefaultTenant(oidcConfig);
var defaultTenantTlsSupport = tlsSupport.forConfig(defaultTenantConfig.tls());
this.defaultPolicyEnforcer = createPolicyEnforcer(defaultTenantConfig, config.defaultTenant(),
defaultTenantTlsSupport);
Expand All @@ -69,13 +68,13 @@ public Uni<PolicyEnforcer> resolvePolicyEnforcer(RoutingContext routingContext,
return Uni.createFrom().item(defaultPolicyEnforcer);
}
if (dynamicConfigResolver == null) {
return Uni.createFrom().item(getStaticPolicyEnforcer(tenantConfig.tenantId.get()));
return Uni.createFrom().item(getStaticPolicyEnforcer(tenantConfig.tenantId().get()));
} else {
return getDynamicPolicyEnforcer(routingContext, tenantConfig)
.onItem().ifNull().continueWith(new Supplier<PolicyEnforcer>() {
@Override
public PolicyEnforcer get() {
return getStaticPolicyEnforcer(tenantConfig.tenantId.get());
return getStaticPolicyEnforcer(tenantConfig.tenantId().get());
}
});
}
Expand Down Expand Up @@ -114,7 +113,7 @@ private static Map<String, PolicyEnforcer> createNamedPolicyEnforcers(OidcConfig

Map<String, PolicyEnforcer> policyEnforcerTenants = new HashMap<>();
for (Map.Entry<String, KeycloakPolicyEnforcerTenantConfig> tenant : config.namedTenants().entrySet()) {
OidcTenantConfig oidcTenantConfig = getOidcTenantConfig(oidcConfig, tenant.getKey());
var oidcTenantConfig = getOidcTenantConfig(oidcConfig, tenant.getKey());
policyEnforcerTenants.put(tenant.getKey(),
createPolicyEnforcer(oidcTenantConfig, tenant.getValue(), tlsSupport.forConfig(oidcTenantConfig.tls())));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;

import io.quarkus.oidc.OIDCException;
import io.quarkus.oidc.OidcTenantConfig;
import io.quarkus.oidc.common.runtime.OidcTlsSupport.TlsConfigSupport;
import io.quarkus.oidc.common.runtime.config.OidcCommonConfig;
import io.quarkus.oidc.runtime.OidcConfig;
import io.quarkus.oidc.runtime.OidcTenantConfig;
import io.quarkus.runtime.configuration.ConfigurationException;

public final class KeycloakPolicyEnforcerUtil {
Expand All @@ -33,14 +33,14 @@ static PolicyEnforcer createPolicyEnforcer(OidcTenantConfig oidcConfig,
KeycloakPolicyEnforcerTenantConfig keycloakPolicyEnforcerConfig,
TlsConfigSupport tlsConfigSupport) {

if (oidcConfig.applicationType
if (oidcConfig.applicationType()
.orElse(OidcTenantConfig.ApplicationType.SERVICE) == OidcTenantConfig.ApplicationType.WEB_APP
&& oidcConfig.roles.source.orElse(null) != OidcTenantConfig.Roles.Source.accesstoken) {
&& oidcConfig.roles().source().orElse(null) != OidcTenantConfig.Roles.Source.accesstoken) {
throw new OIDCException("Application 'web-app' type is only supported if access token is the source of roles");
}

AdapterConfig adapterConfig = new AdapterConfig();
String authServerUrl = oidcConfig.getAuthServerUrl().get();
String authServerUrl = oidcConfig.authServerUrl().get();

try {
adapterConfig.setRealm(authServerUrl.substring(authServerUrl.lastIndexOf('/') + 1));
Expand All @@ -49,7 +49,7 @@ static PolicyEnforcer createPolicyEnforcer(OidcTenantConfig oidcConfig,
throw new ConfigurationException("Failed to parse the realm name.", cause);
}

adapterConfig.setResource(oidcConfig.getClientId().get());
adapterConfig.setResource(oidcConfig.clientId().get());
adapterConfig.setCredentials(getCredentials(oidcConfig));

if (!tlsConfigSupport.useTlsRegistry()) {
Expand All @@ -70,12 +70,12 @@ static PolicyEnforcer createPolicyEnforcer(OidcTenantConfig oidcConfig,
}
adapterConfig.setConnectionPoolSize(keycloakPolicyEnforcerConfig.connectionPoolSize());

if (oidcConfig.proxy.host.isPresent()) {
String host = oidcConfig.proxy.host.get();
if (oidcConfig.proxy().host().isPresent()) {
String host = oidcConfig.proxy().host().get();
if (!host.startsWith("http://") && !host.startsWith("https://")) {
host = URI.create(authServerUrl).getScheme() + "://" + host;
}
adapterConfig.setProxyUrl(host + ":" + oidcConfig.proxy.port);
adapterConfig.setProxyUrl(host + ":" + oidcConfig.proxy().port());
}

PolicyEnforcerConfig enforcerConfig = getPolicyEnforcerConfig(keycloakPolicyEnforcerConfig);
Expand All @@ -95,7 +95,7 @@ static PolicyEnforcer createPolicyEnforcer(OidcTenantConfig oidcConfig,

private static Map<String, Object> getCredentials(OidcTenantConfig oidcConfig) {
Map<String, Object> credentials = new HashMap<>();
Optional<String> clientSecret = oidcConfig.getCredentials().getSecret();
Optional<String> clientSecret = oidcConfig.credentials().secret();

if (clientSecret.isPresent()) {
credentials.put("secret", clientSecret.orElse(null));
Expand Down Expand Up @@ -226,13 +226,13 @@ private static boolean isNotComplexConfigKey(String key) {

static OidcTenantConfig getOidcTenantConfig(OidcConfig oidcConfig, String tenant) {
if (tenant == null || DEFAULT_TENANT_ID.equals(tenant)) {
return new OidcTenantConfig(OidcConfig.getDefaultTenant(oidcConfig), DEFAULT_TENANT_ID);
return OidcConfig.getDefaultTenant(oidcConfig);
}

var oidcTenantConfig = oidcConfig.namedTenants().get(tenant);
if (oidcTenantConfig == null) {
throw new ConfigurationException("Failed to find a matching OidcTenantConfig for tenant: " + tenant);
}
return new OidcTenantConfig(oidcTenantConfig, tenant);
return oidcTenantConfig;
}
}
Loading

0 comments on commit bb052ce

Please sign in to comment.