diff --git a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityConfig.java b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityConfig.java index 3b267255a15c0..4821e78172252 100644 --- a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityConfig.java +++ b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityConfig.java @@ -4,31 +4,32 @@ import java.util.Optional; import java.util.Set; -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; +import io.smallrye.config.WithName; /** * */ -@ConfigRoot(phase = ConfigPhase.BUILD_TIME) -public final class SecurityConfig { +@ConfigMapping(prefix = "quarkus.security") +@ConfigRoot +public interface SecurityConfig { /** * Whether authorization is enabled in dev mode or not. In other launch modes authorization is always enabled. */ - @ConfigItem(name = "auth.enabled-in-dev-mode", defaultValue = "true") - public boolean authorizationEnabledInDevMode; + @WithName("auth.enabled-in-dev-mode") + @WithDefault("true") + boolean authorizationEnabledInDevMode(); /** * List of security providers to register */ - @ConfigItem - public Optional> securityProviders; + Optional> securityProviders(); /** * Security provider configuration */ - @ConfigItem - public Map securityProviderConfig; + Map securityProviderConfig(); } diff --git a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java index 8aa777f640b67..ce61a24f2eeae 100644 --- a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java +++ b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java @@ -127,7 +127,7 @@ public class SecurityProcessor { void produceJcaSecurityProviders(BuildProducer jcaProviders, BuildProducer bouncyCastleProvider, BuildProducer bouncyCastleJsseProvider) { - Set providers = security.securityProviders.orElse(Set.of()); + Set providers = security.securityProviders().orElse(Set.of()); for (String providerName : providers) { if (SecurityProviderUtils.BOUNCYCASTLE_PROVIDER_NAME.equals(providerName)) { bouncyCastleProvider.produce(new BouncyCastleProviderBuildItem()); @@ -138,7 +138,8 @@ void produceJcaSecurityProviders(BuildProducer jcaProvider } else if (SecurityProviderUtils.BOUNCYCASTLE_FIPS_JSSE_PROVIDER_NAME.equals(providerName)) { bouncyCastleJsseProvider.produce(new BouncyCastleJsseProviderBuildItem(true)); } else { - jcaProviders.produce(new JCAProviderBuildItem(providerName, security.securityProviderConfig.get(providerName))); + jcaProviders + .produce(new JCAProviderBuildItem(providerName, security.securityProviderConfig().get(providerName))); } log.debugf("Added providerName: %s", providerName); } @@ -412,7 +413,7 @@ void addBouncyCastleExportsToNativeImage(BuildProducer jpms } } - private Optional getOne(List items) { + private static Optional getOne(List items) { if (items.size() > 1) { throw new IllegalStateException("Only a single Bouncy Castle registration can be provided."); } @@ -425,7 +426,7 @@ private Optional getOne(List items) { * @param providerName - JCA provider name * @return class names that make up the provider and its services */ - private List registerProvider(String providerName, + private static List registerProvider(String providerName, String providerConfig, BuildProducer additionalProviders) { List providerClasses = new ArrayList<>(); @@ -496,7 +497,7 @@ void transformAdditionalSecuredClassesToMethods(List transformers, List additionalSecuredMethods, SecurityBuildTimeConfig config) { - if (config.denyUnannotated) { + if (config.denyUnannotated()) { transformers.produce(new AnnotationsTransformerBuildItem(new DenyingUnannotatedTransformer())); } if (!additionalSecuredMethods.isEmpty()) { @@ -543,7 +544,7 @@ void gatherSecurityChecks(BuildProducer syntheticBeans, IndexView index = beanArchiveBuildItem.getIndex(); Map securityChecks = gatherSecurityAnnotations(index, configExpSecurityCheckProducer, - additionalSecured.values(), config.denyUnannotated, recorder, configBuilderProducer, + additionalSecured.values(), config.denyUnannotated(), recorder, configBuilderProducer, reflectiveClassBuildItemBuildProducer, rolesAllowedConfigExpResolverBuildItems); for (AdditionalSecurityCheckBuildItem additionalSecurityCheck : additionalSecurityChecks) { securityChecks.put(additionalSecurityCheck.getMethodInfo(), @@ -596,7 +597,7 @@ public void resolveConfigExpressionRoles(Optional gatherSecurityAnnotations(IndexView index, + private static Map gatherSecurityAnnotations(IndexView index, BuildProducer configExpSecurityCheckProducer, Collection additionalSecuredMethods, boolean denyUnannotated, SecurityCheckRecorder recorder, BuildProducer configBuilderProducer, @@ -775,7 +776,7 @@ private static Set getSetForKey(String[] allowedRoles) { return new HashSet<>(Arrays.asList(allowedRoles)); } - private boolean alreadyHasAnnotation(AnnotationInstance alreadyExistingInstance, DotName annotationName) { + private static boolean alreadyHasAnnotation(AnnotationInstance alreadyExistingInstance, DotName annotationName) { return alreadyExistingInstance.target().kind() == AnnotationTarget.Kind.METHOD && alreadyExistingInstance.name().equals(annotationName); } @@ -785,7 +786,7 @@ static boolean isPublicNonStaticNonConstructor(MethodInfo methodInfo) { && !"".equals(methodInfo.name()); } - private void gatherSecurityAnnotations( + private static void gatherSecurityAnnotations( IndexView index, DotName dotName, Map alreadyCheckedMethods, Map classLevelAnnotations, @@ -845,7 +846,7 @@ void registerAdditionalBeans(BuildProducer beans) { @BuildStep AdditionalBeanBuildItem authorizationController(LaunchModeBuildItem launchMode) { Class controllerClass = AuthorizationController.class; - if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT && !security.authorizationEnabledInDevMode) { + if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT && !security.authorizationEnabledInDevMode()) { controllerClass = DevModeDisabledAuthorizationController.class; } return AdditionalBeanBuildItem.builder().addBeanClass(controllerClass).build(); @@ -915,7 +916,7 @@ static class AdditionalSecured { } } - class SecurityCheckStorageAppPredicate implements Predicate { + static class SecurityCheckStorageAppPredicate implements Predicate { @Override public boolean test(String s) { diff --git a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityBuildTimeConfig.java b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityBuildTimeConfig.java index fe0593c55c396..a44a306be1a3d 100644 --- a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityBuildTimeConfig.java +++ b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityBuildTimeConfig.java @@ -1,14 +1,17 @@ package io.quarkus.security.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; +import io.smallrye.config.WithName; /** * @author Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com */ -@ConfigRoot(name = "security", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) -public class SecurityBuildTimeConfig { +@ConfigMapping(prefix = "quarkus.security") +@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) +public interface SecurityBuildTimeConfig { /** * If set to true, access to all methods of beans that have any security annotations on other members will be denied by * default. @@ -27,7 +30,8 @@ public class SecurityBuildTimeConfig { * } * */ - @ConfigItem(name = "deny-unannotated-members") - public boolean denyUnannotated; + @WithName("deny-unannotated-members") + @WithDefault("false") + boolean denyUnannotated(); } diff --git a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/check/PermissionSecurityCheck.java b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/check/PermissionSecurityCheck.java index 5888f5e2c792d..680c5326a1f66 100644 --- a/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/check/PermissionSecurityCheck.java +++ b/extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/check/PermissionSecurityCheck.java @@ -71,10 +71,14 @@ public boolean requiresMethodArguments() { } private static void throwException(SecurityIdentity identity) { + throw getException(identity); + } + + private static RuntimeException getException(SecurityIdentity identity) { if (identity.isAnonymous()) { - throw new UnauthorizedException(); + return new UnauthorizedException(); } else { - throw new ForbiddenException(); + return new ForbiddenException(); } } @@ -103,7 +107,7 @@ protected Uni checkPermissions(SecurityIdentity identity, Permission permissi public Uni apply(Boolean hasPermission) { if (FALSE.equals(hasPermission)) { // check failed - throwException(identity); + return Uni.createFrom().failure(getException(identity)); } return SUCCESSFUL_CHECK; @@ -214,7 +218,7 @@ public Uni apply(Boolean hasPermission) { final boolean hasAnotherPermission = i + 1 < permissions.length; if (!hasAnotherPermission) { // check failed - throwException(identity); + return Uni.createFrom().failure(getException(identity)); } // check next permission