Skip to content

Commit

Permalink
Merge pull request #44374 from sberyozkin/optimize_oidc_tenants_grouping
Browse files Browse the repository at this point in the history
Improve the way OIDC tenants are grouped and their properties are generated
  • Loading branch information
sberyozkin authored Nov 9, 2024
2 parents 76cba8c + 3f10b51 commit 3321050
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class DefaultPolicyEnforcerResolver implements PolicyEnforcerResolver {
this.tlsSupport = OidcTlsSupport.empty();
}

var defaultTenantConfig = new OidcTenantConfig(oidcConfig.defaultTenant(), OidcUtils.DEFAULT_TENANT_ID);
var defaultTenantConfig = new OidcTenantConfig(OidcConfig.getDefaultTenant(oidcConfig), OidcUtils.DEFAULT_TENANT_ID);
var defaultTenantTlsSupport = tlsSupport.forConfig(defaultTenantConfig.tls);
this.defaultPolicyEnforcer = createPolicyEnforcer(defaultTenantConfig, config.defaultTenant(),
defaultTenantTlsSupport);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ 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.defaultTenant(), DEFAULT_TENANT_ID);
return new OidcTenantConfig(OidcConfig.getDefaultTenant(oidcConfig), DEFAULT_TENANT_ID);
}

var oidcTenantConfig = oidcConfig.namedTenants().get(tenant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.WithDefault;

Expand Down Expand Up @@ -36,10 +37,14 @@ public interface OidcClientCommonConfig extends OidcCommonConfig {
Optional<String> clientName();

/**
* Credentials the OIDC adapter uses to authenticate to the OIDC server.
* Different authentication options for OIDC client to access OIDC token and other secured endpoints.
*/
@ConfigDocSection
Credentials credentials();

/**
* Credentials used by OIDC client to authenticate to OIDC token and other secured endpoints.
*/
interface Credentials {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.OptionalInt;

import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.WithDefault;

Expand Down Expand Up @@ -77,13 +78,15 @@ public interface OidcCommonConfig {
boolean followRedirects();

/**
* Options to configure the proxy the OIDC adapter uses to talk with the OIDC server.
* HTTP proxy configuration.
*/
@ConfigDocSection
Proxy proxy();

/**
* TLS configurations
* TLS configuration.
*/
@ConfigDocSection
Tls tls();

interface Tls {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.oidc.deployment;

import io.quarkus.oidc.runtime.OidcConfig;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
Expand All @@ -18,8 +19,9 @@ public interface OidcBuildTimeConfig {
boolean enabled();

/**
* Dev UI configuration.
* OIDC Dev UI configuration which is effective in dev mode only.
*/
@ConfigDocSection
DevUiConfig devui();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void logout() {
@Path("access-token-name")
@GET
public String accessTokenName() {
if (!config.defaultTenant().authentication().verifyAccessToken()) {
if (!OidcConfig.getDefaultTenant(config).authentication().verifyAccessToken()) {
throw new IllegalStateException("Access token verification should be enabled");
}
return accessToken.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ public class ProtectedResourceWithJwtAccessToken {

@GET
public String getName() {
return idToken.getName() + ":" + config.defaultTenant().authentication().verifyAccessToken();
return idToken.getName() + ":" + OidcConfig.getDefaultTenant(config).authentication().verifyAccessToken();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public class ProtectedResourceWithoutJwtAccessToken {

@GET
public String getName() {
return idToken.getName() + ":" + config.defaultTenant().authentication().verifyAccessToken();
return idToken.getName() + ":" + OidcConfig.getDefaultTenant(config).authentication().verifyAccessToken();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public BackChannelLogoutHandler(OidcConfig oidcConfig) {
}

public void setup(@Observes Router router) {
addRoute(router, new OidcTenantConfig(oidcConfig.defaultTenant(), OidcUtils.DEFAULT_TENANT_ID));
addRoute(router, new OidcTenantConfig(OidcConfig.getDefaultTenant(oidcConfig), OidcUtils.DEFAULT_TENANT_ID));

for (var nameToOidcTenantConfig : oidcConfig.namedTenants().entrySet()) {
addRoute(router, new OidcTenantConfig(nameToOidcTenantConfig.getValue(), nameToOidcTenantConfig.getKey()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithDefaults;
import io.smallrye.config.WithParentName;
import io.smallrye.config.WithUnnamedKey;

@ConfigMapping(prefix = "quarkus.oidc")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface OidcConfig {

/**
* The default tenant.
*/
@WithParentName
OidcTenantConfig defaultTenant();
String DEFAULT_TENANT_KEY = "<default>";

/**
* Additional named tenants.
*/
@ConfigDocSection
@ConfigDocMapKey("tenant")
@WithParentName
@WithUnnamedKey(DEFAULT_TENANT_KEY)
@WithDefaults
Map<String, OidcTenantConfig> namedTenants();

/**
* Default TokenIntrospection and UserInfo Cache configuration which is used for all the tenants if it is enabled
* with the build-time 'quarkus.oidc.default-token-cache-enabled' property ('true' by default) and also activated,
* see its `max-size` property.
* Default TokenIntrospection and UserInfo Cache configuration.
* It is used for all the tenants if it is enabled with the build-time 'quarkus.oidc.default-token-cache-enabled' property
* ('true' by default) and also activated, see its `max-size` property.
*/
@ConfigDocSection
TokenCache tokenCache();

/**
Expand Down Expand Up @@ -66,4 +66,13 @@ interface TokenCache {
*/
Optional<Duration> cleanUpTimerInterval();
}

static io.quarkus.oidc.runtime.OidcTenantConfig getDefaultTenant(OidcConfig config) {
for (var tenant : config.namedTenants().entrySet()) {
if (OidcConfig.DEFAULT_TENANT_KEY.equals(tenant.getKey())) {
return tenant.getValue();
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public TenantConfigBean setup(OidcConfig config, Vertx vertxValue, OidcTlsSuppor
boolean userInfoInjectionPointDetected) {
OidcRecorder.userInfoInjectionPointDetected = userInfoInjectionPointDetected;

var defaultTenant = new OidcTenantConfig(config.defaultTenant(), DEFAULT_TENANT_ID);
var defaultTenant = new OidcTenantConfig(OidcConfig.getDefaultTenant(config), DEFAULT_TENANT_ID);
String defaultTenantId = defaultTenant.getTenantId().get();
var defaultTenantInitializer = createStaticTenantContextCreator(vertxValue, defaultTenant,
!config.namedTenants().isEmpty(), defaultTenantId, tlsSupport);
Expand All @@ -120,6 +120,9 @@ public TenantConfigBean setup(OidcConfig config, Vertx vertxValue, OidcTlsSuppor

Map<String, TenantConfigContext> staticTenantsConfig = new HashMap<>();
for (var tenant : config.namedTenants().entrySet()) {
if (OidcConfig.DEFAULT_TENANT_KEY.equals(tenant.getKey())) {
continue;
}
var namedTenantConfig = new OidcTenantConfig(tenant.getValue(), tenant.getKey());
OidcCommonUtils.verifyConfigurationId(defaultTenantId, tenant.getKey(), namedTenantConfig.getTenantId());
var staticTenantInitializer = createStaticTenantContextCreator(vertxValue, namedTenantConfig, false,
Expand Down Expand Up @@ -709,7 +712,7 @@ private TenantSpecificOidcIdentityProvider(String tenantId) {
this.blockingExecutor = Arc.container().instance(BlockingSecurityExecutor.class).get();
if (tenantId.equals(DEFAULT_TENANT_ID)) {
OidcConfig config = Arc.container().instance(OidcConfig.class).get();
this.tenantId = config.defaultTenant().tenantId().orElse(OidcUtils.DEFAULT_TENANT_ID);
this.tenantId = OidcConfig.getDefaultTenant(config).tenantId().orElse(OidcUtils.DEFAULT_TENANT_ID);
} else {
this.tenantId = tenantId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.quarkus.oidc.common.runtime.config.OidcCommonConfig;
import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.configuration.TrimmedStringConverter;
import io.quarkus.security.identity.SecurityIdentityAugmentor;
import io.smallrye.config.WithConverter;
Expand Down Expand Up @@ -103,14 +104,16 @@ public interface OidcTenantConfig extends OidcClientCommonConfig {
Optional<String> publicKey();

/**
* Introspection Basic Authentication which must be configured only if the introspection is required
* and OpenId Connect Provider does not support the OIDC client authentication configured with
* Optional introspection endpoint-specific basic authentication configuration.
* It must be configured only if the introspection is required
* but OpenId Connect Provider does not support the OIDC client authentication configured with
* {@link OidcCommonConfig#credentials} for its introspection endpoint.
*/
@ConfigDocSection
IntrospectionCredentials introspectionCredentials();

/**
* Introspection Basic Authentication configuration
* Optional introspection endpoint-specific authentication configuration.
*/
interface IntrospectionCredentials {
/**
Expand All @@ -132,18 +135,21 @@ interface IntrospectionCredentials {
}

/**
* Configuration to find and parse a custom claim containing the roles information.
* Configuration to find and parse custom claims which contain roles.
*/
@ConfigDocSection
Roles roles();

/**
* Configuration how to validate the token claims.
* Configuration to customize validation of token claims.
*/
@ConfigDocSection
Token token();

/**
* RP Initiated, BackChannel and FrontChannel Logout configuration
* RP-initiated, back-channel and front-channel logout configuration.
*/
@ConfigDocSection
Logout logout();

/**
Expand All @@ -161,8 +167,12 @@ interface IntrospectionCredentials {
* If the truststore does not have the leaf certificate imported, then the leaf certificate must be identified by its Common
* Name.
*/
@ConfigDocSection
CertificateChain certificateChain();

/**
* Configuration of the certificate chain which can be used to verify tokens.
*/
interface CertificateChain {
/**
* Common name of the leaf certificate. It must be set if the {@link #trustStoreFile} does not have
Expand Down Expand Up @@ -196,18 +206,21 @@ interface CertificateChain {
}

/**
* Different options to configure authorization requests
* Configuration for managing an authorization code flow.
*/
@ConfigDocSection
Authentication authentication();

/**
* Authorization code grant configuration
* Configuration to complete an authorization code flow grant.
*/
@ConfigDocSection
CodeGrant codeGrant();

/**
* Default token state manager configuration
*/
@ConfigDocSection
TokenStateManager tokenStateManager();

/**
Expand Down Expand Up @@ -317,8 +330,9 @@ interface Backchannel {
}

/**
* Configuration for controlling how JsonWebKeySet containing verification keys should be acquired and managed.
* How JsonWebKey verification key set should be acquired and managed.
*/
@ConfigDocSection
Jwks jwks();

interface Jwks {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class OidcEventResource {
private final String expectedAuthServerUrl;

public OidcEventResource(OidcEventObserver oidcEventObserver, OidcConfig oidcConfig) {
this.expectedAuthServerUrl = dropTrailingSlash(oidcConfig.defaultTenant().authServerUrl().get());
this.expectedAuthServerUrl = dropTrailingSlash(OidcConfig.getDefaultTenant(oidcConfig).authServerUrl().get());
this.oidcEventObserver = oidcEventObserver;
}

Expand Down

0 comments on commit 3321050

Please sign in to comment.