From 35ad0d51eaaf1258d5fa745f0d9b6e07c4631278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Sun, 17 Mar 2024 16:21:37 +0100 Subject: [PATCH 1/4] Migrate Elytron Security Properties File from config class to @ConfigMapping --- .../ElytronPropertiesProcessor.java | 36 ++++++-------- .../ElytronPropertiesFileRecorder.java | 49 ++++++++++--------- .../security/runtime/MPRealmConfig.java | 36 +++----------- .../runtime/MPRealmRuntimeConfig.java | 29 +++++------ .../runtime/PropertiesRealmConfig.java | 37 ++++++-------- .../security/runtime/SecurityUsersConfig.java | 14 +++--- 6 files changed, 86 insertions(+), 115 deletions(-) diff --git a/extensions/elytron-security-properties-file/deployment/src/main/java/io/quarkus/elytron/security/properties/deployment/ElytronPropertiesProcessor.java b/extensions/elytron-security-properties-file/deployment/src/main/java/io/quarkus/elytron/security/properties/deployment/ElytronPropertiesProcessor.java index 5186a83b05afb..db623f9ba66be 100644 --- a/extensions/elytron-security-properties-file/deployment/src/main/java/io/quarkus/elytron/security/properties/deployment/ElytronPropertiesProcessor.java +++ b/extensions/elytron-security-properties-file/deployment/src/main/java/io/quarkus/elytron/security/properties/deployment/ElytronPropertiesProcessor.java @@ -29,10 +29,6 @@ */ class ElytronPropertiesProcessor { private static final Logger log = Logger.getLogger(ElytronPropertiesProcessor.class.getName()); - /** Prefix for the user to password mapping properties */ - private static final String USERS_PREFIX = "quarkus.security.embedded.users"; - /** Prefix for the user to password mapping properties */ - private static final String ROLES_PREFIX = "quarkus.security.embedded.roles"; SecurityUsersConfig propertiesConfig; @@ -57,31 +53,32 @@ FeatureBuildItem feature() { @BuildStep @Record(ExecutionTime.RUNTIME_INIT) void configureFileRealmAuthConfig(ElytronPropertiesFileRecorder recorder, - BuildProducer resources, BuildProducer securityRealm) throws Exception { - if (propertiesConfig.file.enabled) { - PropertiesRealmConfig realmConfig = propertiesConfig.file; - log.debugf("Configuring from PropertiesRealmConfig, users=%s, roles=%s", realmConfig.users, - realmConfig.roles); + if (propertiesConfig.file().enabled()) { + PropertiesRealmConfig realmConfig = propertiesConfig.file(); + log.debugf("Configuring from PropertiesRealmConfig, users=%s, roles=%s", realmConfig.users(), + realmConfig.roles()); // Have the runtime recorder create the LegacyPropertiesSecurityRealm and create the build item - RuntimeValue realm = recorder.createRealm(realmConfig); + RuntimeValue realm = recorder.createRealm(propertiesConfig); securityRealm - .produce(new SecurityRealmBuildItem(realm, realmConfig.realmName, recorder.loadRealm(realm, realmConfig))); + .produce( + new SecurityRealmBuildItem(realm, realmConfig.realmName(), + recorder.loadRealm(realm, propertiesConfig))); // Return the realm authentication mechanism build item } } @BuildStep void nativeResource(BuildProducer resources) throws Exception { - if (propertiesConfig.file.enabled) { - PropertiesRealmConfig realmConfig = propertiesConfig.file; - resources.produce(new NativeImageResourceBuildItem(realmConfig.users, realmConfig.roles)); + if (propertiesConfig.file().enabled()) { + PropertiesRealmConfig realmConfig = propertiesConfig.file(); + resources.produce(new NativeImageResourceBuildItem(realmConfig.users(), realmConfig.roles())); } } @BuildStep ElytronPasswordMarkerBuildItem marker() { - if (propertiesConfig.file.enabled || propertiesConfig.embedded.enabled) { + if (propertiesConfig.file().enabled() || propertiesConfig.embedded().enabled()) { return new ElytronPasswordMarkerBuildItem(); } return null; @@ -103,14 +100,13 @@ ElytronPasswordMarkerBuildItem marker() { void configureMPRealmConfig(ElytronPropertiesFileRecorder recorder, BuildProducer securityRealm, MPRealmRuntimeConfig runtimeConfig) throws Exception { - if (propertiesConfig.embedded.enabled) { - MPRealmConfig realmConfig = propertiesConfig.embedded; + if (propertiesConfig.embedded().enabled()) { log.info("Configuring from MPRealmConfig"); - RuntimeValue realm = recorder.createRealm(realmConfig); + RuntimeValue realm = recorder.createEmbeddedRealm(propertiesConfig); securityRealm - .produce(new SecurityRealmBuildItem(realm, realmConfig.realmName, - recorder.loadRealm(realm, realmConfig, runtimeConfig))); + .produce(new SecurityRealmBuildItem(realm, propertiesConfig.embedded().realmName(), + recorder.loadEmbeddedRealm(realm, propertiesConfig, runtimeConfig))); } } } diff --git a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronPropertiesFileRecorder.java b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronPropertiesFileRecorder.java index db6bd5bb8d44b..d89c8b46bba3d 100644 --- a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronPropertiesFileRecorder.java +++ b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronPropertiesFileRecorder.java @@ -48,41 +48,42 @@ public class ElytronPropertiesFileRecorder { * Load the user.properties and roles.properties files into the {@linkplain SecurityRealm} * * @param realm - a {@linkplain LegacyPropertiesSecurityRealm} - * @param config - realm configuration info + * @param propertiesConfig - properties config with a realm configuration info * @throws Exception */ - public Runnable loadRealm(RuntimeValue realm, PropertiesRealmConfig config) throws Exception { + public Runnable loadRealm(RuntimeValue realm, SecurityUsersConfig propertiesConfig) throws Exception { return new Runnable() { @Override public void run() { try { + PropertiesRealmConfig config = propertiesConfig.file(); log.debugf("loadRealm, config=%s", config); SecurityRealm secRealm = realm.getValue(); if (!(secRealm instanceof LegacyPropertiesSecurityRealm)) { return; } - log.debugf("Trying to loader users: /%s", config.users); + log.debugf("Trying to loader users: /%s", config.users()); URL users; - Path p = Paths.get(config.users); + Path p = Paths.get(config.users()); if (Files.exists(p)) { users = p.toUri().toURL(); } else { - users = Thread.currentThread().getContextClassLoader().getResource(config.users); + users = Thread.currentThread().getContextClassLoader().getResource(config.users()); } log.debugf("users: %s", users); - log.debugf("Trying to loader roles: %s", config.roles); + log.debugf("Trying to loader roles: %s", config.roles()); URL roles; - p = Paths.get(config.roles); + p = Paths.get(config.roles()); if (Files.exists(p)) { roles = p.toUri().toURL(); } else { - roles = Thread.currentThread().getContextClassLoader().getResource(config.roles); + roles = Thread.currentThread().getContextClassLoader().getResource(config.roles()); } log.debugf("roles: %s", roles); if (users == null && roles == null) { String msg = String.format( "No PropertiesRealmConfig users/roles settings found. Configure the quarkus.security.file.%s properties", - config.help()); + PropertiesRealmConfig.help()); throw new IllegalStateException(msg); } LegacyPropertiesSecurityRealm propsRealm = (LegacyPropertiesSecurityRealm) secRealm; @@ -110,14 +111,16 @@ public void run() { * Load the embedded user and role information into the {@linkplain SecurityRealm} * * @param realm - a {@linkplain SimpleMapBackedSecurityRealm} - * @param config - the realm config + * @param propertiesConfig - properties config with the realm config * @throws Exception */ - public Runnable loadRealm(RuntimeValue realm, MPRealmConfig config, MPRealmRuntimeConfig runtimeConfig) + public Runnable loadEmbeddedRealm(RuntimeValue realm, SecurityUsersConfig propertiesConfig, + MPRealmRuntimeConfig runtimeConfig) throws Exception { return new Runnable() { @Override public void run() { + MPRealmConfig config = propertiesConfig.embedded(); log.debugf("loadRealm, config=%s", config); SecurityRealm secRealm = realm.getValue(); if (!(secRealm instanceof SimpleMapBackedSecurityRealm)) { @@ -125,15 +128,15 @@ public void run() { } SimpleMapBackedSecurityRealm memRealm = (SimpleMapBackedSecurityRealm) secRealm; HashMap identityMap = new HashMap<>(); - Map userInfo = runtimeConfig.users; + Map userInfo = runtimeConfig.users(); log.debugf("UserInfoMap: %s%n", userInfo); - Map roleInfo = runtimeConfig.roles; + Map roleInfo = runtimeConfig.roles(); log.debugf("RoleInfoMap: %s%n", roleInfo); for (Map.Entry userPasswordEntry : userInfo.entrySet()) { Password password; String user = userPasswordEntry.getKey(); - if (runtimeConfig.plainText) { + if (runtimeConfig.plainText()) { password = ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR, userPasswordEntry.getValue().toCharArray()); } else { @@ -142,9 +145,9 @@ public void run() { .asUtf8String().hexDecode().drain(); password = PasswordFactory - .getInstance(runtimeConfig.algorithm.getName(), + .getInstance(runtimeConfig.algorithm().getName(), new WildFlyElytronPasswordProvider()) - .generatePassword(new DigestPasswordSpec(user, config.realmName, hashed)); + .generatePassword(new DigestPasswordSpec(user, config.realmName(), hashed)); } catch (Exception e) { throw new RuntimeException("Unable to register password for user:" + user + " make sure it is a valid hex encoded MD5 hash", e); @@ -172,22 +175,23 @@ public void run() { /** * Create a runtime value for a {@linkplain LegacyPropertiesSecurityRealm} * - * @param config - the realm config + * @param propertiesConfig - properties config * @return - runtime value wrapper for the SecurityRealm * @throws Exception */ - public RuntimeValue createRealm(PropertiesRealmConfig config) throws Exception { + public RuntimeValue createRealm(SecurityUsersConfig propertiesConfig) throws Exception { + PropertiesRealmConfig config = propertiesConfig.file(); log.debugf("createRealm, config=%s", config); SecurityRealm realm = LegacyPropertiesSecurityRealm.builder() - .setDefaultRealm(config.realmName) + .setDefaultRealm(config.realmName()) .setProviders(new Supplier() { @Override public Provider[] get() { return PROVIDERS; } }) - .setPlainText(config.plainText) + .setPlainText(config.plainText()) .build(); return new RuntimeValue<>(realm); } @@ -195,11 +199,12 @@ public Provider[] get() { /** * Create a runtime value for a {@linkplain SimpleMapBackedSecurityRealm} * - * @param config - the realm config + * @param propertiesConfig - properties config with the realm config * @return - runtime value wrapper for the SecurityRealm * @throws Exception */ - public RuntimeValue createRealm(MPRealmConfig config) { + public RuntimeValue createEmbeddedRealm(SecurityUsersConfig propertiesConfig) { + MPRealmConfig config = propertiesConfig.embedded(); log.debugf("createRealm, config=%s", config); Supplier providers = new Supplier() { diff --git a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmConfig.java b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmConfig.java index d573b9610edbe..a249554c152f3 100644 --- a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmConfig.java +++ b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmConfig.java @@ -1,48 +1,26 @@ package io.quarkus.elytron.security.runtime; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; /** * Configuration information used to populate a {@linkplain org.wildfly.security.auth.realm.SimpleMapBackedSecurityRealm} * } */ @ConfigGroup -public class MPRealmConfig { +public interface MPRealmConfig { /** * The realm name. This is used when generating a hashed password */ - @ConfigItem(defaultValue = "Quarkus") - public String realmName; + @WithDefault("Quarkus") + String realmName(); /** * Determine whether security via the embedded realm is enabled. */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); - public String getRealmName() { - return realmName; - } - - public void setRealmName(String realmName) { - this.realmName = realmName; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - public String toString() { - return "MPRealmConfig{" + - "realmName='" + realmName + '\'' + - ", enabled=" + enabled + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmRuntimeConfig.java b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmRuntimeConfig.java index d6f348ed8dd45..9143b60477246 100644 --- a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmRuntimeConfig.java +++ b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/MPRealmRuntimeConfig.java @@ -4,48 +4,49 @@ import org.wildfly.security.password.interfaces.DigestPassword; -import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigDocDefault; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; -import io.quarkus.runtime.annotations.ConvertWith; import io.quarkus.runtime.configuration.TrimmedStringConverter; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithConverter; +import io.smallrye.config.WithDefault; /** * Configuration information used to populate a {@linkplain org.wildfly.security.auth.realm.SimpleMapBackedSecurityRealm} * } */ -@ConfigRoot(name = "security.users.embedded", phase = ConfigPhase.RUN_TIME) -public class MPRealmRuntimeConfig { +@ConfigMapping(prefix = "quarkus.security.users.embedded") +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +public interface MPRealmRuntimeConfig { /** * If the properties are stored in plain text. If this is false (the default) then it is expected * that the passwords are of the form HEX( MD5( username ":" realm ":" password ) ) */ - @ConfigItem - public boolean plainText; + @WithDefault("false") + boolean plainText(); /** * Determine which algorithm to use. *

* This property is ignored if {@code plainText} is true. */ - @ConfigItem(defaultValue = DigestPassword.ALGORITHM_DIGEST_MD5) - public DigestAlgorithm algorithm; + @WithDefault(DigestPassword.ALGORITHM_DIGEST_MD5) + DigestAlgorithm algorithm(); /** * The realm users user1=password\nuser2=password2... mapping. * See Embedded Users. */ - @ConfigItem(defaultValueDocumentation = "none") - @ConvertWith(TrimmedStringConverter.class) - public Map users; + @ConfigDocDefault("none") + Map<@WithConverter(TrimmedStringConverter.class) String, @WithConverter(TrimmedStringConverter.class) String> users(); /** * The realm roles user1=role1,role2,...\nuser2=role1,role2,... mapping * See Embedded Roles. */ - @ConfigItem(defaultValueDocumentation = "none") - @ConvertWith(TrimmedStringConverter.class) - public Map roles; + @ConfigDocDefault("none") + Map<@WithConverter(TrimmedStringConverter.class) String, @WithConverter(TrimmedStringConverter.class) String> roles(); } diff --git a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/PropertiesRealmConfig.java b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/PropertiesRealmConfig.java index e11469947d530..9e4aa8b5e95b8 100644 --- a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/PropertiesRealmConfig.java +++ b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/PropertiesRealmConfig.java @@ -1,7 +1,7 @@ package io.quarkus.elytron.security.runtime; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; /** * A configuration object for a properties resource based realm configuration, @@ -15,53 +15,44 @@ * user2=role21,role2,...,roleN2 */ @ConfigGroup -public class PropertiesRealmConfig { +public interface PropertiesRealmConfig { /** * The realm name. This is used when generating a hashed password */ - @ConfigItem(defaultValue = "Quarkus") - public String realmName; + @WithDefault("Quarkus") + String realmName(); /** * Determine whether security via the file realm is enabled. */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); /** * If the properties are stored in plain text. If this is false (the default) then it is expected * that the passwords are of the form HEX( MD5( username ":" realm ":" password ) ) */ - @ConfigItem - public boolean plainText; + @WithDefault("false") + boolean plainText(); /** * Classpath resource name of properties file containing user to password mappings. See * Users.properties. */ - @ConfigItem(defaultValue = "users.properties") - public String users; + @WithDefault("users.properties") + String users(); /** * Classpath resource name of properties file containing user to role mappings. See * Roles.properties. */ - @ConfigItem(defaultValue = "roles.properties") - public String roles; + @WithDefault("roles.properties") + String roles(); - public String help() { + static String help() { return "{enabled,users,roles,realm-name,plain-text}"; } - @Override - public String toString() { - return "PropertiesRealmConfig{" + - ", realmName='" + realmName + '\'' + - ", enabled=" + enabled + - ", users='" + users + '\'' + - ", roles='" + roles + '\'' + - ", plainText=" + plainText + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/SecurityUsersConfig.java b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/SecurityUsersConfig.java index ec2a931be9895..d9bc9f3918c70 100644 --- a/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/SecurityUsersConfig.java +++ b/extensions/elytron-security-properties-file/runtime/src/main/java/io/quarkus/elytron/security/runtime/SecurityUsersConfig.java @@ -1,26 +1,26 @@ package io.quarkus.elytron.security.runtime; import io.quarkus.runtime.annotations.ConfigDocSection; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; /** * */ -@ConfigRoot(name = "security.users", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) -public final class SecurityUsersConfig { +@ConfigMapping(prefix = "quarkus.security.users") +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public interface SecurityUsersConfig { /** * Property Files Realm Configuration */ - @ConfigItem @ConfigDocSection - public PropertiesRealmConfig file; + PropertiesRealmConfig file(); + /** * Embedded Realm Configuration */ - @ConfigItem @ConfigDocSection - public MPRealmConfig embedded; + MPRealmConfig embedded(); } From 088b602928bec0324902e54f4bd2f55653678184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Thu, 14 Mar 2024 07:19:56 +0100 Subject: [PATCH 2/4] Migrate Elytron OAuth2 from config classes to @ConfigMapping --- .../deployment/OAuth2DeploymentProcessor.java | 12 ++---------- .../oauth2/runtime/OAuth2BuildTimeConfig.java | 16 +++++++++------- .../oauth2/runtime/OAuth2Recorder.java | 16 ++++++++-------- .../oauth2/runtime/OAuth2RuntimeConfig.java | 19 ++++++++----------- 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/extensions/elytron-security-oauth2/deployment/src/main/java/io/quarkus/elytron/security/oauth2/deployment/OAuth2DeploymentProcessor.java b/extensions/elytron-security-oauth2/deployment/src/main/java/io/quarkus/elytron/security/oauth2/deployment/OAuth2DeploymentProcessor.java index 2c9f858563826..f12ae8c7842ba 100644 --- a/extensions/elytron-security-oauth2/deployment/src/main/java/io/quarkus/elytron/security/oauth2/deployment/OAuth2DeploymentProcessor.java +++ b/extensions/elytron-security-oauth2/deployment/src/main/java/io/quarkus/elytron/security/oauth2/deployment/OAuth2DeploymentProcessor.java @@ -21,7 +21,6 @@ import io.quarkus.elytron.security.oauth2.runtime.auth.OAuth2AuthMechanism; import io.quarkus.runtime.RuntimeValue; import io.quarkus.security.identity.SecurityIdentityAugmentor; -import io.quarkus.vertx.http.deployment.SecurityInformationBuildItem; /** * The build time process for the OAUth2 security aspects of the deployment. This creates {@linkplain BuildStep}s for @@ -57,7 +56,7 @@ AdditionalBeanBuildItem configureOauth2RealmAuthConfig(OAuth2Recorder recorder, OAuth2BuildTimeConfig oauth2BuildTimeConfig, OAuth2RuntimeConfig oauth2RuntimeConfig, BuildProducer securityRealm) throws Exception { - if (!oauth2BuildTimeConfig.enabled) { + if (!oauth2BuildTimeConfig.enabled()) { return null; } @@ -68,19 +67,12 @@ AdditionalBeanBuildItem configureOauth2RealmAuthConfig(OAuth2Recorder recorder, @BuildStep ElytronTokenMarkerBuildItem marker(OAuth2BuildTimeConfig oauth2BuildTimeConfig) { - if (!oauth2BuildTimeConfig.enabled) { + if (!oauth2BuildTimeConfig.enabled()) { return null; } return new ElytronTokenMarkerBuildItem(); } - void provideSecurityInformation(OAuth2BuildTimeConfig oauth2BuildTimeConfig, - BuildProducer securityInformationProducer) { - if (oauth2BuildTimeConfig.enabled) { - securityInformationProducer.produce(SecurityInformationBuildItem.OAUTH2()); - } - } - @BuildStep @Record(ExecutionTime.STATIC_INIT) SyntheticBeanBuildItem augmentor(OAuth2Recorder recorder, diff --git a/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2BuildTimeConfig.java b/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2BuildTimeConfig.java index 0a5af11e340b9..4d975dee0bf04 100644 --- a/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2BuildTimeConfig.java +++ b/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2BuildTimeConfig.java @@ -1,25 +1,27 @@ package io.quarkus.elytron.security.oauth2.runtime; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; /** * See https://docs.wildfly.org/14/WildFly_Elytron_Security.html#validating-oauth2-bearer-tokens */ -@ConfigRoot(name = "oauth2", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) -public class OAuth2BuildTimeConfig { +@ConfigMapping(prefix = "quarkus.oauth2") +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public interface OAuth2BuildTimeConfig { /** * Determine if the OAuth2 extension is enabled. Enabled by default if you include the * elytron-security-oauth2 dependency, so this would be used to disable it. */ - @ConfigItem(defaultValue = "true") - public boolean enabled; + @WithDefault("true") + boolean enabled(); /** * The claim that is used in the introspection endpoint response to load the roles. */ - @ConfigItem(defaultValue = "scope") - public String roleClaim; + @WithDefault("scope") + String roleClaim(); } diff --git a/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2Recorder.java b/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2Recorder.java index edbe4adea9126..64cd0ce35b141 100644 --- a/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2Recorder.java +++ b/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2Recorder.java @@ -33,18 +33,18 @@ public class OAuth2Recorder { public RuntimeValue createRealm(OAuth2RuntimeConfig runtimeConfig) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, KeyManagementException { - if (!runtimeConfig.clientId.isPresent() || !runtimeConfig.clientSecret.isPresent() - || !runtimeConfig.introspectionUrl.isPresent()) { + if (!runtimeConfig.clientId().isPresent() || !runtimeConfig.clientSecret().isPresent() + || !runtimeConfig.introspectionUrl().isPresent()) { throw new ConfigurationException( "client-id, client-secret and introspection-url must be configured when the oauth2 extension is enabled"); } OAuth2IntrospectValidator.Builder validatorBuilder = OAuth2IntrospectValidator.builder() - .clientId(runtimeConfig.clientId.get()) - .clientSecret(runtimeConfig.clientSecret.get()) - .tokenIntrospectionUrl(URI.create(runtimeConfig.introspectionUrl.get()).toURL()); + .clientId(runtimeConfig.clientId().get()) + .clientSecret(runtimeConfig.clientSecret().get()) + .tokenIntrospectionUrl(URI.create(runtimeConfig.introspectionUrl().get()).toURL()); - if (runtimeConfig.caCertFile.isPresent()) { + if (runtimeConfig.caCertFile().isPresent()) { validatorBuilder.useSslContext(createSSLContext(runtimeConfig)); } else { validatorBuilder.useSslContext(SSLContext.getDefault()); @@ -74,7 +74,7 @@ private Map attributesToMap(Attributes claims) { private SSLContext createSSLContext(OAuth2RuntimeConfig runtimeConfig) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { - try (InputStream is = new FileInputStream(runtimeConfig.caCertFile.get())) { + try (InputStream is = new FileInputStream(runtimeConfig.caCertFile().get())) { CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate caCert = (X509Certificate) cf.generateCertificate(is); @@ -94,7 +94,7 @@ private SSLContext createSSLContext(OAuth2RuntimeConfig runtimeConfig) } public RuntimeValue augmentor(OAuth2BuildTimeConfig buildTimeConfig) { - return new RuntimeValue<>(new OAuth2Augmentor(buildTimeConfig.roleClaim)); + return new RuntimeValue<>(new OAuth2Augmentor(buildTimeConfig.roleClaim())); } } diff --git a/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2RuntimeConfig.java b/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2RuntimeConfig.java index 9a6f3ccac9db0..116aad655b285 100644 --- a/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2RuntimeConfig.java +++ b/extensions/elytron-security-oauth2/runtime/src/main/java/io/quarkus/elytron/security/oauth2/runtime/OAuth2RuntimeConfig.java @@ -2,42 +2,39 @@ import java.util.Optional; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; /** * See https://docs.wildfly.org/14/WildFly_Elytron_Security.html#validating-oauth2-bearer-tokens */ -@ConfigRoot(name = "oauth2", phase = ConfigPhase.RUN_TIME) -public class OAuth2RuntimeConfig { +@ConfigMapping(prefix = "quarkus.oauth2") +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +public interface OAuth2RuntimeConfig { /** * The OAuth2 client id used to validate the token. * Mandatory if the extension is enabled. */ - @ConfigItem - public Optional clientId; + Optional clientId(); /** * The OAuth2 client secret used to validate the token. * Mandatory if the extension is enabled. */ - @ConfigItem - public Optional clientSecret; + Optional clientSecret(); /** * The OAuth2 introspection endpoint URL used to validate the token and gather the authentication claims. * Mandatory if the extension is enabled. */ - @ConfigItem - public Optional introspectionUrl; + Optional introspectionUrl(); /** * The OAuth2 server certificate file. Warning: this is not supported in native mode where the certificate * must be included in the truststore used during the native image generation, see * Using SSL With Native Executables. */ - @ConfigItem - public Optional caCertFile; + Optional caCertFile(); } From 6236798ef88bcdc481e658816ea61ab32c8a1ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Sun, 17 Mar 2024 19:54:24 +0100 Subject: [PATCH 3/4] Migrate Elytron LDAP from config classes to @ConfigMapping --- .../ElytronSecurityLdapProcessor.java | 6 +-- .../LdapSecurityRealmBuildTimeConfig.java | 24 +++++------- .../elytron/security/ldap/LdapRecorder.java | 38 +++++++++--------- .../ldap/config/AttributeMappingConfig.java | 17 ++++---- .../ldap/config/DirContextConfig.java | 39 +++++++------------ .../ldap/config/IdentityMappingConfig.java | 30 +++++--------- .../LdapSecurityRealmRuntimeConfig.java | 27 +++++-------- 7 files changed, 72 insertions(+), 109 deletions(-) diff --git a/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/ElytronSecurityLdapProcessor.java b/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/ElytronSecurityLdapProcessor.java index 334838ff56729..67444ff5a8bde 100644 --- a/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/ElytronSecurityLdapProcessor.java +++ b/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/ElytronSecurityLdapProcessor.java @@ -44,17 +44,17 @@ void configureLdapRealmAuthConfig(LdapRecorder recorder, BuildProducer securityRealm, BeanContainerBuildItem beanContainerBuildItem //we need this to make sure ArC is initialized ) throws Exception { - if (!ldapSecurityRealmBuildTimeConfig.enabled) { + if (!ldapSecurityRealmBuildTimeConfig.enabled()) { return; } RuntimeValue realm = recorder.createRealm(ldapSecurityRealmRuntimeConfig); - securityRealm.produce(new SecurityRealmBuildItem(realm, ldapSecurityRealmBuildTimeConfig.realmName, null)); + securityRealm.produce(new SecurityRealmBuildItem(realm, ldapSecurityRealmBuildTimeConfig.realmName(), null)); } @BuildStep ElytronPasswordMarkerBuildItem marker(LdapSecurityRealmBuildTimeConfig ldapSecurityRealmBuildTimeConfig) { - if (!ldapSecurityRealmBuildTimeConfig.enabled) { + if (!ldapSecurityRealmBuildTimeConfig.enabled()) { return null; } return new ElytronPasswordMarkerBuildItem(); diff --git a/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/config/LdapSecurityRealmBuildTimeConfig.java b/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/config/LdapSecurityRealmBuildTimeConfig.java index 336941bc789ca..752f67822c583 100644 --- a/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/config/LdapSecurityRealmBuildTimeConfig.java +++ b/extensions/elytron-security-ldap/deployment/src/main/java/io/quarkus/elytron/security/ldap/deployment/config/LdapSecurityRealmBuildTimeConfig.java @@ -1,33 +1,29 @@ package io.quarkus.elytron.security.ldap.deployment.config; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; /** * A configuration object for an LDAP based realm configuration, * {@linkplain org.wildfly.security.auth.realm.ldap.LdapSecurityRealm} */ -@ConfigRoot(name = "security.ldap", phase = ConfigPhase.BUILD_TIME) -public class LdapSecurityRealmBuildTimeConfig { +@ConfigMapping(prefix = "quarkus.security.ldap") +@ConfigRoot(phase = ConfigPhase.BUILD_TIME) +public interface LdapSecurityRealmBuildTimeConfig { /** * The option to enable the ldap elytron module */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); /** * The elytron realm name */ - @ConfigItem(defaultValue = "Quarkus") - public String realmName; + @WithDefault("Quarkus") + String realmName(); - @Override - public String toString() { - return "LdapSecurityRealmBuildTimeConfig{" + - "enabled=" + enabled + - ", realmName='" + realmName + '\'' + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/LdapRecorder.java b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/LdapRecorder.java index d25fc8ed6426f..71aaec3f65fdd 100644 --- a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/LdapRecorder.java +++ b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/LdapRecorder.java @@ -30,44 +30,44 @@ public class LdapRecorder { */ public RuntimeValue createRealm(LdapSecurityRealmRuntimeConfig runtimeConfig) { LdapSecurityRealmBuilder.IdentityMappingBuilder identityMappingBuilder = LdapSecurityRealmBuilder.builder() - .setDirContextSupplier(createDirContextSupplier(runtimeConfig.dirContext)) + .setDirContextSupplier(createDirContextSupplier(runtimeConfig.dirContext())) .identityMapping(); - if (runtimeConfig.identityMapping.searchRecursive) { + if (runtimeConfig.identityMapping().searchRecursive()) { identityMappingBuilder.searchRecursive(); } LdapSecurityRealmBuilder ldapSecurityRealmBuilder = identityMappingBuilder - .map(createAttributeMappings(runtimeConfig.identityMapping)) - .setRdnIdentifier(runtimeConfig.identityMapping.rdnIdentifier) - .setSearchDn(runtimeConfig.identityMapping.searchBaseDn) + .map(createAttributeMappings(runtimeConfig.identityMapping())) + .setRdnIdentifier(runtimeConfig.identityMapping().rdnIdentifier()) + .setSearchDn(runtimeConfig.identityMapping().searchBaseDn()) .build(); - if (runtimeConfig.directVerification) { + if (runtimeConfig.directVerification()) { ldapSecurityRealmBuilder.addDirectEvidenceVerification(false); } return new RuntimeValue<>(ldapSecurityRealmBuilder.build()); } - private ExceptionSupplier createDirContextSupplier(DirContextConfig dirContext) { + private static ExceptionSupplier createDirContextSupplier(DirContextConfig dirContext) { DirContextFactory dirContextFactory = new QuarkusDirContextFactory( - dirContext.url, - dirContext.principal.orElse(null), - dirContext.password.orElse(null), - dirContext.connectTimeout, - dirContext.readTimeout); - return () -> dirContextFactory.obtainDirContext(dirContext.referralMode); + dirContext.url(), + dirContext.principal().orElse(null), + dirContext.password().orElse(null), + dirContext.connectTimeout(), + dirContext.readTimeout()); + return () -> dirContextFactory.obtainDirContext(dirContext.referralMode()); } - private AttributeMapping[] createAttributeMappings(IdentityMappingConfig identityMappingConfig) { + private static AttributeMapping[] createAttributeMappings(IdentityMappingConfig identityMappingConfig) { List attributeMappings = new ArrayList<>(); - for (AttributeMappingConfig attributeMappingConfig : identityMappingConfig.attributeMappings.values()) { - attributeMappings.add(AttributeMapping.fromFilter(attributeMappingConfig.filter) - .from(attributeMappingConfig.from) - .to(attributeMappingConfig.to) - .searchDn(attributeMappingConfig.filterBaseDn) + for (AttributeMappingConfig attributeMappingConfig : identityMappingConfig.attributeMappings().values()) { + attributeMappings.add(AttributeMapping.fromFilter(attributeMappingConfig.filter()) + .from(attributeMappingConfig.from()) + .to(attributeMappingConfig.to()) + .searchDn(attributeMappingConfig.filterBaseDn()) .build()); } diff --git a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/AttributeMappingConfig.java b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/AttributeMappingConfig.java index 5a933bf81e9de..a41243b350551 100644 --- a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/AttributeMappingConfig.java +++ b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/AttributeMappingConfig.java @@ -1,35 +1,32 @@ package io.quarkus.elytron.security.ldap.config; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; /** * Configuration information used to populate a {@linkplain org.wildfly.security.auth.realm.ldap.AttributeMapping} */ @ConfigGroup -public class AttributeMappingConfig { +public interface AttributeMappingConfig { /** * The roleAttributeId from which is mapped (e.g. "cn") */ - @ConfigItem - public String from; + String from(); /** * The identifier whom the attribute is mapped to (in Quarkus: "groups", in WildFly this is "Roles") */ - @ConfigItem(defaultValue = "groups") - public String to; + @WithDefault("groups") + String to(); /** * The filter (also named "roleFilter") */ - @ConfigItem - public String filter; + String filter(); /** * The filter base dn (also named "rolesContextDn") */ - @ConfigItem - public String filterBaseDn; + String filterBaseDn(); } diff --git a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/DirContextConfig.java b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/DirContextConfig.java index 97d731bd01381..e7582cc947ff8 100644 --- a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/DirContextConfig.java +++ b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/DirContextConfig.java @@ -6,56 +6,43 @@ import org.wildfly.security.auth.realm.ldap.DirContextFactory; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; @ConfigGroup -public class DirContextConfig { +public interface DirContextConfig { /** * The url of the ldap server */ - @ConfigItem - public String url; + String url(); /** * The principal: user which is used to connect to ldap server (also named "bindDn") */ - @ConfigItem - public Optional principal; + Optional principal(); /** * The password which belongs to the principal (also named "bindCredential") */ - @ConfigItem - public Optional password; + Optional password(); /** * how ldap redirects are handled */ - @ConfigItem(defaultValue = "ignore") - public DirContextFactory.ReferralMode referralMode; + @WithDefault("ignore") + DirContextFactory.ReferralMode referralMode(); /** * The connect timeout */ - @ConfigItem(defaultValue = "5s") - public Duration connectTimeout; + @WithDefault("5s") + Duration connectTimeout(); /** * The read timeout */ - @ConfigItem(defaultValue = "60s") - public Duration readTimeout; - - @Override - public String toString() { - return "DirContextConfig{" + - "url='" + url + '\'' + - ", principal=" + principal + - ", password=" + password + - ", referralMode=" + referralMode + - ", connectTimeout=" + connectTimeout + - ", readTimeout=" + readTimeout + - '}'; - } + @WithDefault("60s") + Duration readTimeout(); + + String toString(); } diff --git a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/IdentityMappingConfig.java b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/IdentityMappingConfig.java index db7b13acba608..67f3c545831c4 100644 --- a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/IdentityMappingConfig.java +++ b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/IdentityMappingConfig.java @@ -3,42 +3,32 @@ import java.util.Map; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; @ConfigGroup -public class IdentityMappingConfig { +public interface IdentityMappingConfig { /** * The identifier which correlates to the provided user (also named "baseFilter") */ - @ConfigItem(defaultValue = "uid") - public String rdnIdentifier; + @WithDefault("uid") + String rdnIdentifier(); /** * The dn where we look for users */ - @ConfigItem - public String searchBaseDn; + String searchBaseDn(); /** * If the child nodes are also searched for identities */ - @ConfigItem(defaultValue = "false") - public boolean searchRecursive; + @WithDefault("false") + boolean searchRecursive(); /** * The configs how we get from the attribute to the Role */ - @ConfigItem - public Map attributeMappings; - - @Override - public String toString() { - return "IdentityMappingConfig{" + - "rdnIdentifier='" + rdnIdentifier + '\'' + - ", searchBaseDn='" + searchBaseDn + '\'' + - ", searchRecursive=" + searchRecursive + - ", attributeMappings=" + attributeMappings + - '}'; - } + Map attributeMappings(); + + String toString(); } diff --git a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/LdapSecurityRealmRuntimeConfig.java b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/LdapSecurityRealmRuntimeConfig.java index f1e1e351d5269..b49eebd8b0bae 100644 --- a/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/LdapSecurityRealmRuntimeConfig.java +++ b/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/config/LdapSecurityRealmRuntimeConfig.java @@ -1,40 +1,33 @@ package io.quarkus.elytron.security.ldap.config; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; /** * Runtime configuration object for an LDAP based realm configuration, * {@linkplain org.wildfly.security.auth.realm.ldap.LdapSecurityRealm} */ -@ConfigRoot(name = "security.ldap", phase = ConfigPhase.RUN_TIME) -public class LdapSecurityRealmRuntimeConfig { +@ConfigMapping(prefix = "quarkus.security.ldap") +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +public interface LdapSecurityRealmRuntimeConfig { /** * Provided credentials are verified against ldap? */ - @ConfigItem(defaultValue = "true") - public boolean directVerification; + @WithDefault("true") + boolean directVerification(); /** * The ldap server configuration */ - @ConfigItem - public DirContextConfig dirContext; + DirContextConfig dirContext(); /** * The config which we use to map an identity */ - @ConfigItem - public IdentityMappingConfig identityMapping; + IdentityMappingConfig identityMapping(); - @Override - public String toString() { - return "LdapSecurityRealmRuntimeConfig{" + - "directVerification=" + directVerification + - ", dirContext=" + dirContext + - ", identityMapping=" + identityMapping + - '}'; - } + String toString(); } From 9678bc5ae7e01ac7f430d815594d279c6e5b2a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Sun, 17 Mar 2024 20:09:04 +0100 Subject: [PATCH 4/4] Migrate Elytron Security JDBC config classes to @ConfigMappin --- .../ElytronSecurityJdbcProcessor.java | 6 +- .../security/jdbc/AttributeMappingConfig.java | 19 ++----- .../jdbc/BcryptPasswordKeyMapperConfig.java | 55 ++++++++----------- .../jdbc/ClearPasswordMapperConfig.java | 27 ++++----- .../elytron/security/jdbc/JdbcRecorder.java | 24 ++++---- .../JdbcSecurityRealmBuildTimeConfig.java | 24 ++++---- .../jdbc/JdbcSecurityRealmRuntimeConfig.java | 19 +++---- .../jdbc/PasswordKeyMapperConfig.java | 11 ---- .../security/jdbc/PrincipalQueriesConfig.java | 20 +++---- .../security/jdbc/PrincipalQueryConfig.java | 33 ++++------- 10 files changed, 88 insertions(+), 150 deletions(-) delete mode 100644 extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PasswordKeyMapperConfig.java diff --git a/extensions/elytron-security-jdbc/deployment/src/main/java/io/quarkus/elytron/security/jdbc/deployment/ElytronSecurityJdbcProcessor.java b/extensions/elytron-security-jdbc/deployment/src/main/java/io/quarkus/elytron/security/jdbc/deployment/ElytronSecurityJdbcProcessor.java index 6c1bd15f2978a..994b33ee7838e 100644 --- a/extensions/elytron-security-jdbc/deployment/src/main/java/io/quarkus/elytron/security/jdbc/deployment/ElytronSecurityJdbcProcessor.java +++ b/extensions/elytron-security-jdbc/deployment/src/main/java/io/quarkus/elytron/security/jdbc/deployment/ElytronSecurityJdbcProcessor.java @@ -48,17 +48,17 @@ void configureJdbcRealmAuthConfig(JdbcRecorder recorder, BuildProducer securityRealm, BeanContainerBuildItem beanContainerBuildItem, //we need this to make sure ArC is initialized List dataSourcesConfigured) throws Exception { - if (!jdbcSecurityRealmBuildTimeConfig.enabled) { + if (!jdbcSecurityRealmBuildTimeConfig.enabled()) { return; } RuntimeValue realm = recorder.createRealm(jdbcSecurityRealmRuntimeConfig); - securityRealm.produce(new SecurityRealmBuildItem(realm, jdbcSecurityRealmBuildTimeConfig.realmName, null)); + securityRealm.produce(new SecurityRealmBuildItem(realm, jdbcSecurityRealmBuildTimeConfig.realmName(), null)); } @BuildStep ElytronPasswordMarkerBuildItem marker(JdbcSecurityRealmBuildTimeConfig jdbcSecurityRealmBuildTimeConfig) { - if (!jdbcSecurityRealmBuildTimeConfig.enabled) { + if (!jdbcSecurityRealmBuildTimeConfig.enabled()) { return null; } return new ElytronPasswordMarkerBuildItem(); diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/AttributeMappingConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/AttributeMappingConfig.java index f7ab3d5ca80c4..92d5d26d421f1 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/AttributeMappingConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/AttributeMappingConfig.java @@ -1,31 +1,24 @@ package io.quarkus.elytron.security.jdbc; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; /** * Configuration information used to populate a {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.AttributeMapper} */ @ConfigGroup -public class AttributeMappingConfig { +public interface AttributeMappingConfig { /** * The index (1 based numbering) of column to map */ - @ConfigItem - public int index; + @WithDefault("0") + int index(); /** * The target attribute name */ - @ConfigItem - public String to; + String to(); - @Override - public String toString() { - return "AttributeMappingConfig{" + - "index=" + index + - ", to='" + to + '\'' + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/BcryptPasswordKeyMapperConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/BcryptPasswordKeyMapperConfig.java index a293c3dcd6b04..5848f998f5836 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/BcryptPasswordKeyMapperConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/BcryptPasswordKeyMapperConfig.java @@ -4,74 +4,63 @@ import org.wildfly.security.password.spec.Encoding; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; /** * Configuration information used to populate a "bcrypt" * {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper} */ @ConfigGroup -public class BcryptPasswordKeyMapperConfig implements PasswordKeyMapperConfig { +public interface BcryptPasswordKeyMapperConfig { - public static final String BCRYPT = "bcrypt"; + String BCRYPT = "bcrypt"; /** * If the bcrypt-password-mapper is enabled. */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); /** * The index (1 based numbering) of the column containing the password hash */ - @ConfigItem - public int passwordIndex; + @WithDefault("0") + int passwordIndex(); /** * A string referencing the password hash encoding ("BASE64" or "HEX") */ - @ConfigItem(defaultValue = "BASE64") - public Encoding hashEncoding; + @WithDefault("BASE64") + Encoding hashEncoding(); /** * The index (1 based numbering) of the column containing the Bcrypt salt */ - @ConfigItem - public int saltIndex; + @WithDefault("0") + int saltIndex(); /** * A string referencing the salt encoding ("BASE64" or "HEX") */ - @ConfigItem(defaultValue = "BASE64") - public Encoding saltEncoding; + @WithDefault("BASE64") + Encoding saltEncoding(); /** * The index (1 based numbering) of the column containing the Bcrypt iteration count */ - @ConfigItem - public int iterationCountIndex; + @WithDefault("0") + int iterationCountIndex(); - @Override - public PasswordKeyMapper toPasswordKeyMapper() { + default PasswordKeyMapper toPasswordKeyMapper() { return PasswordKeyMapper.builder() .setDefaultAlgorithm(BCRYPT) - .setHashColumn(passwordIndex) - .setHashEncoding(hashEncoding) - .setSaltColumn(saltIndex) - .setSaltEncoding(saltEncoding) - .setIterationCountColumn(iterationCountIndex) + .setHashColumn(passwordIndex()) + .setHashEncoding(hashEncoding()) + .setSaltColumn(saltIndex()) + .setSaltEncoding(saltEncoding()) + .setIterationCountColumn(iterationCountIndex()) .build(); } - @Override - public String toString() { - return "BcryptPasswordKeyMapperConfig{" + - "enabled=" + enabled + - ", passwordIndex=" + passwordIndex + - ", hashEncoding=" + hashEncoding + - ", saltIndex=" + saltIndex + - ", saltEncoding=" + saltEncoding + - ", iterationCountIndex=" + iterationCountIndex + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/ClearPasswordMapperConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/ClearPasswordMapperConfig.java index 653e2ad807458..413b3ba1aaf5e 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/ClearPasswordMapperConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/ClearPasswordMapperConfig.java @@ -3,42 +3,35 @@ import org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithDefault; /** * Configuration information used to populate a "clear" * {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper} */ @ConfigGroup -public class ClearPasswordMapperConfig implements PasswordKeyMapperConfig { +public interface ClearPasswordMapperConfig { - public static final String CLEAR = "clear"; + String CLEAR = "clear"; /** * If the clear-password-mapper is enabled. */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); /** * The index (1 based numbering) of the column containing the clear password */ - @ConfigItem(defaultValue = "1") - public int passwordIndex; + @WithDefault("1") + int passwordIndex(); - @Override - public PasswordKeyMapper toPasswordKeyMapper() { + default PasswordKeyMapper toPasswordKeyMapper() { return PasswordKeyMapper.builder() .setDefaultAlgorithm(CLEAR) - .setHashColumn(passwordIndex) + .setHashColumn(passwordIndex()) .build(); } - @Override - public String toString() { - return "ClearPasswordMapperConfig{" + - "enabled=" + enabled + - ", passwordIndex=" + passwordIndex + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcRecorder.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcRecorder.java index a31f01522cb2a..075b6dde8eb85 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcRecorder.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcRecorder.java @@ -35,38 +35,38 @@ public Provider[] get() { } }; JdbcSecurityRealmBuilder builder = JdbcSecurityRealm.builder().setProviders(providers); - PrincipalQueriesConfig principalQueries = config.principalQueries; - registerPrincipalQuery(principalQueries.defaultPrincipalQuery, builder); - principalQueries.namedPrincipalQueries + PrincipalQueriesConfig principalQueries = config.principalQueries(); + registerPrincipalQuery(principalQueries.defaultPrincipalQuery(), builder); + principalQueries.namedPrincipalQueries() .forEach((name, principalQuery) -> registerPrincipalQuery(principalQuery, builder)); return new RuntimeValue<>(builder.build()); } private void registerPrincipalQuery(PrincipalQueryConfig principalQuery, JdbcSecurityRealmBuilder builder) { - QueryBuilder queryBuilder = builder.principalQuery(principalQuery.sql.orElseThrow( + QueryBuilder queryBuilder = builder.principalQuery(principalQuery.sql().orElseThrow( () -> new IllegalStateException("quarkus.security.jdbc.principal-query.sql property must be set"))) .from(getDataSource(principalQuery)); - AttributeMapper[] mappers = principalQuery.attributeMappings.entrySet() + AttributeMapper[] mappers = principalQuery.attributeMappings().entrySet() .stream() - .map(entry -> new AttributeMapper(entry.getValue().index, entry.getValue().to)) + .map(entry -> new AttributeMapper(entry.getValue().index(), entry.getValue().to())) .toArray(size -> new AttributeMapper[size]); queryBuilder.withMapper(mappers); - if (principalQuery.clearPasswordMapperConfig.enabled) { - queryBuilder.withMapper(principalQuery.clearPasswordMapperConfig.toPasswordKeyMapper()); + if (principalQuery.clearPasswordMapperConfig().enabled()) { + queryBuilder.withMapper(principalQuery.clearPasswordMapperConfig().toPasswordKeyMapper()); } - if (principalQuery.bcryptPasswordKeyMapperConfig.enabled) { - queryBuilder.withMapper(principalQuery.bcryptPasswordKeyMapperConfig.toPasswordKeyMapper()); + if (principalQuery.bcryptPasswordKeyMapperConfig().enabled()) { + queryBuilder.withMapper(principalQuery.bcryptPasswordKeyMapperConfig().toPasswordKeyMapper()); } } private DataSource getDataSource(PrincipalQueryConfig principalQuery) { - if (principalQuery.datasource.isPresent()) { + if (principalQuery.datasource().isPresent()) { return Arc.container() .instance(DataSource.class, - new io.quarkus.agroal.DataSource.DataSourceLiteral(principalQuery.datasource.get())) + new io.quarkus.agroal.DataSource.DataSourceLiteral(principalQuery.datasource().get())) .get(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmBuildTimeConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmBuildTimeConfig.java index 4fcfdb989a8cc..35fcb45e185f3 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmBuildTimeConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmBuildTimeConfig.java @@ -1,33 +1,29 @@ package io.quarkus.elytron.security.jdbc; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; /** * A configuration object for a jdbc based realm configuration, * {@linkplain org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm} */ -@ConfigRoot(name = "security.jdbc", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) -public class JdbcSecurityRealmBuildTimeConfig { +@ConfigMapping(prefix = "quarkus.security.jdbc") +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public interface JdbcSecurityRealmBuildTimeConfig { /** * The realm name */ - @ConfigItem(defaultValue = "Quarkus") - public String realmName; + @WithDefault("Quarkus") + String realmName(); /** * If the properties store is enabled. */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); - @Override - public String toString() { - return "JdbcRealmConfig{" + - ", realmName='" + realmName + '\'' + - ", enabled=" + enabled + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmRuntimeConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmRuntimeConfig.java index f3cfa790e7982..940ebbbf5fb09 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmRuntimeConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/JdbcSecurityRealmRuntimeConfig.java @@ -1,27 +1,24 @@ package io.quarkus.elytron.security.jdbc; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithName; /** * A configuration object for a jdbc based realm configuration, * {@linkplain org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm} */ -@ConfigRoot(name = "security.jdbc", phase = ConfigPhase.RUN_TIME) -public class JdbcSecurityRealmRuntimeConfig { +@ConfigMapping(prefix = "quarkus.security.jdbc") +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +public interface JdbcSecurityRealmRuntimeConfig { /** * The principal-queries config */ - @ConfigItem(name = "principal-query") - public PrincipalQueriesConfig principalQueries; + @WithName("principal-query") + PrincipalQueriesConfig principalQueries(); // https://github.com/wildfly/wildfly-core/blob/main/elytron/src/test/resources/org/wildfly/extension/elytron/security-realms.xml#L18 - @Override - public String toString() { - return "JdbcRealmConfig{" + - "principalQueries=" + principalQueries + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PasswordKeyMapperConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PasswordKeyMapperConfig.java deleted file mode 100644 index b0309f719e368..0000000000000 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PasswordKeyMapperConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.quarkus.elytron.security.jdbc; - -import org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper; - -/** - * Convert the current object into an instance of {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper} - */ -public interface PasswordKeyMapperConfig { - - PasswordKeyMapper toPasswordKeyMapper(); -} diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueriesConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueriesConfig.java index 329b88649556f..febd771c645e5 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueriesConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueriesConfig.java @@ -3,31 +3,25 @@ import java.util.Map; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithParentName; /** * Container for a default and optionals named {@linkplain io.quarkus.elytron.security.runtime.jdbc.PrincipalQueryConfig} */ @ConfigGroup -public class PrincipalQueriesConfig { +public interface PrincipalQueriesConfig { /** * The default principal query */ - @ConfigItem(name = ConfigItem.PARENT) - public PrincipalQueryConfig defaultPrincipalQuery; + @WithParentName + PrincipalQueryConfig defaultPrincipalQuery(); /** * Additional principal queries */ - @ConfigItem(name = ConfigItem.PARENT) - public Map namedPrincipalQueries; + @WithParentName + Map namedPrincipalQueries(); - @Override - public String toString() { - return "PrincipalQueriesConfig{" + - "defaultPrincipalQuery=" + defaultPrincipalQuery + - ", namedPrincipalQueries=" + namedPrincipalQueries + - '}'; - } + String toString(); } diff --git a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueryConfig.java b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueryConfig.java index 85433878212a4..2089a89dbb36a 100644 --- a/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueryConfig.java +++ b/extensions/elytron-security-jdbc/runtime/src/main/java/io/quarkus/elytron/security/jdbc/PrincipalQueryConfig.java @@ -4,53 +4,40 @@ import java.util.Optional; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; +import io.smallrye.config.WithName; /** * Configuration information used to populate a {@linkplain org.wildfly.security.auth.realm.jdbc.QueryBuilder} */ @ConfigGroup -public class PrincipalQueryConfig { +public interface PrincipalQueryConfig { /** * The sql query to find the password */ - @ConfigItem - public Optional sql; + Optional sql(); /** * The data source to use */ - @ConfigItem - public Optional datasource; + Optional datasource(); /** * The definitions of the mapping between the database columns and the identity's attributes */ - @ConfigItem - public Map attributeMappings; + Map attributeMappings(); /** * The "clear-password-mapper" configuration */ - @ConfigItem(name = "clear-password-mapper") - public ClearPasswordMapperConfig clearPasswordMapperConfig; + @WithName("clear-password-mapper") + ClearPasswordMapperConfig clearPasswordMapperConfig(); /** * The "bcrypt-password-mapper" configuration */ - @ConfigItem(name = "bcrypt-password-mapper") - public BcryptPasswordKeyMapperConfig bcryptPasswordKeyMapperConfig; - - @Override - public String toString() { - return "PrincipalQueryConfig{" + - "sql='" + sql + '\'' + - ", datasource='" + datasource + '\'' + - ", attributeMappings=" + attributeMappings + - ", clearPasswordMapperConfig=" + clearPasswordMapperConfig + - ", bcryptPasswordKeyMapperConfig=" + bcryptPasswordKeyMapperConfig + - '}'; - } + @WithName("bcrypt-password-mapper") + BcryptPasswordKeyMapperConfig bcryptPasswordKeyMapperConfig(); + String toString(); }