Skip to content

Commit

Permalink
Improve the way OIDC tenants are grouped and their properties are gen…
Browse files Browse the repository at this point in the history
…erated
  • Loading branch information
sberyozkin committed Nov 7, 2024
1 parent 5d09f38 commit ac5016d
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 27 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 @@ -38,6 +38,9 @@ public interface OidcClientCommonConfig extends OidcCommonConfig {
*/
Credentials credentials();

/**
* Credentials the OIDC adapter uses to authenticate to the OIDC server.
*/
interface Credentials {

/**
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 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
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 ac5016d

Please sign in to comment.