diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpSecurityProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpSecurityProcessor.java index 980bc8aaeaaf02..c6cb4a4ba6d956 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpSecurityProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpSecurityProcessor.java @@ -8,7 +8,6 @@ import jakarta.inject.Singleton; import io.quarkus.arc.deployment.AdditionalBeanBuildItem; -import io.quarkus.arc.deployment.BeanContainerListenerBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; @@ -17,7 +16,6 @@ import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; -import io.quarkus.vertx.http.runtime.PolicyConfig; import io.quarkus.vertx.http.runtime.security.AuthenticatedHttpSecurityPolicy; import io.quarkus.vertx.http.runtime.security.BasicAuthenticationMechanism; import io.quarkus.vertx.http.runtime.security.DenySecurityPolicy; @@ -30,7 +28,6 @@ import io.quarkus.vertx.http.runtime.security.MtlsAuthenticationMechanism; import io.quarkus.vertx.http.runtime.security.PathMatchingHttpSecurityPolicy; import io.quarkus.vertx.http.runtime.security.PermitSecurityPolicy; -import io.quarkus.vertx.http.runtime.security.RolesAllowedHttpSecurityPolicy; import io.quarkus.vertx.http.runtime.security.SupplierImpl; import io.vertx.core.http.ClientAuth; @@ -43,14 +40,8 @@ public void builtins(BuildProducer producer, HttpBu producer.produce(new HttpSecurityPolicyBuildItem("permit", new SupplierImpl<>(new PermitSecurityPolicy()))); producer.produce( new HttpSecurityPolicyBuildItem("authenticated", new SupplierImpl<>(new AuthenticatedHttpSecurityPolicy()))); - if (!buildTimeConfig.auth.permissions.isEmpty()) { - beanProducer.produce(AdditionalBeanBuildItem.unremovableOf(PathMatchingHttpSecurityPolicy.class)); - } - for (Map.Entry e : buildTimeConfig.auth.rolePolicy.entrySet()) { - producer.produce(new HttpSecurityPolicyBuildItem(e.getKey(), - new SupplierImpl<>(new RolesAllowedHttpSecurityPolicy(e.getValue().rolesAllowed)))); - } + beanProducer.produce(AdditionalBeanBuildItem.unremovableOf(PathMatchingHttpSecurityPolicy.class)); } @BuildStep @@ -59,11 +50,11 @@ SyntheticBeanBuildItem initFormAuth( HttpSecurityRecorder recorder, HttpBuildTimeConfig buildTimeConfig, BuildProducer filterBuildItemBuildProducer) { - if (!buildTimeConfig.auth.proactive) { - filterBuildItemBuildProducer.produce(RouteBuildItem.builder().route(buildTimeConfig.auth.form.postLocation) - .handler(recorder.formAuthPostHandler()).build()); - } - if (buildTimeConfig.auth.form.enabled) { + if (buildTimeConfig.auth.form) { + if (!buildTimeConfig.auth.proactive) { + filterBuildItemBuildProducer.produce(RouteBuildItem.builder().route(recorder.getFormPostLocation()) + .handler(recorder.formAuthPostHandler()).build()); + } return SyntheticBeanBuildItem.configure(FormAuthenticationMechanism.class) .types(HttpAuthenticationMechanism.class) .setRuntimeInit() @@ -99,7 +90,7 @@ SyntheticBeanBuildItem initBasicAuth( return null; } boolean basicExplicitlyEnabled = buildTimeConfig.auth.basic.orElse(false); - if ((buildTimeConfig.auth.form.enabled || isMtlsClientAuthenticationEnabled(buildTimeConfig)) + if ((buildTimeConfig.auth.form || isMtlsClientAuthenticationEnabled(buildTimeConfig)) && !basicExplicitlyEnabled) { //if form auth is enabled and we are not then we don't install return null; @@ -110,7 +101,7 @@ SyntheticBeanBuildItem initBasicAuth( .setRuntimeInit() .scope(Singleton.class) .supplier(recorder.setupBasicAuth(buildTimeConfig)); - if (!buildTimeConfig.auth.form.enabled && !isMtlsClientAuthenticationEnabled(buildTimeConfig) + if (!buildTimeConfig.auth.form && !isMtlsClientAuthenticationEnabled(buildTimeConfig) && !basicExplicitlyEnabled) { //if not explicitly enabled we make this a default bean, so it is the fallback if nothing else is defined configurator.defaultBean(); @@ -120,6 +111,24 @@ SyntheticBeanBuildItem initBasicAuth( return configurator.done(); } + @BuildStep + @Record(ExecutionTime.RUNTIME_INIT) + void initPermissions(HttpSecurityRecorder recorder, + Capabilities capabilities, + List httpSecurityPolicyBuildItemList) { + if (capabilities.isPresent(Capability.SECURITY)) { + Map> policyMap = new HashMap<>(); + for (HttpSecurityPolicyBuildItem e : httpSecurityPolicyBuildItemList) { + if (policyMap.containsKey(e.getName())) { + throw new RuntimeException("Multiple HTTP security policies defined with name " + e.getName()); + } + policyMap.put(e.getName(), e.policySupplier); + } + + recorder.initPermissions(policyMap); + } + } + @BuildStep @Record(ExecutionTime.STATIC_INIT) void setupAuthenticationMechanisms( @@ -127,19 +136,10 @@ void setupAuthenticationMechanisms( BuildProducer filterBuildItemBuildProducer, BuildProducer beanProducer, Capabilities capabilities, - BuildProducer beanContainerListenerBuildItemBuildProducer, HttpBuildTimeConfig buildTimeConfig, - List httpSecurityPolicyBuildItemList, BuildProducer securityInformationProducer) { - Map> policyMap = new HashMap<>(); - for (HttpSecurityPolicyBuildItem e : httpSecurityPolicyBuildItemList) { - if (policyMap.containsKey(e.getName())) { - throw new RuntimeException("Multiple HTTP security policies defined with name " + e.getName()); - } - policyMap.put(e.getName(), e.policySupplier); - } - if (!buildTimeConfig.auth.form.enabled && buildTimeConfig.auth.basic.orElse(false)) { + if (!buildTimeConfig.auth.form && buildTimeConfig.auth.basic.orElse(false)) { securityInformationProducer.produce(SecurityInformationBuildItem.BASIC()); } @@ -153,15 +153,6 @@ void setupAuthenticationMechanisms( FilterBuildItem.AUTHENTICATION)); filterBuildItemBuildProducer .produce(new FilterBuildItem(recorder.permissionCheckHandler(), FilterBuildItem.AUTHORIZATION)); - - if (!buildTimeConfig.auth.permissions.isEmpty()) { - beanContainerListenerBuildItemBuildProducer - .produce(new BeanContainerListenerBuildItem(recorder.initPermissions(buildTimeConfig, policyMap))); - } - } else { - if (!buildTimeConfig.auth.permissions.isEmpty()) { - throw new IllegalStateException("HTTP permissions have been set however security is not enabled"); - } } } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java index 4f75d3b374a220..31f5925a8ee2db 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java @@ -4,12 +4,14 @@ import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem; import io.quarkus.vertx.http.deployment.devmode.console.ConfiguredPathInfo; import io.quarkus.vertx.http.runtime.BasicRoute; import io.quarkus.vertx.http.runtime.HandlerType; +import io.quarkus.vertx.http.runtime.RouteCandidate; import io.vertx.core.Handler; import io.vertx.ext.web.Route; import io.vertx.ext.web.Router; @@ -134,6 +136,21 @@ public Builder route(String route) { return this; } + /** + * Creates route if {@code routeCandidate} is resolved to the route path during runtime init. + * If {@code routeCandidate} supplies null, route is not going to be created. + * This way, extensions may create routes from runtime configuration properties. + * + * Only HTTP routes with {@link HandlerType#NORMAL} handler type and no {@code notFoundPage} are supported. + * + * @param routeCandidate route that may be resolved to null during runtime init + * @return Builder + */ + public Builder route(Supplier routeCandidate) { + this.routeFunction = new RouteCandidate(routeCandidate); + return this; + } + /** * @param route A normalized path used to define a basic route * (e.g. use HttpRootPathBuildItem to construct/resolve the path value). This path this is also diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/RuntimeRouteCandidateTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/RuntimeRouteCandidateTest.java new file mode 100644 index 00000000000000..a86948f5f9ad64 --- /dev/null +++ b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/RuntimeRouteCandidateTest.java @@ -0,0 +1,77 @@ +package io.quarkus.vertx.http; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.eclipse.microprofile.config.ConfigProvider; +import org.hamcrest.Matchers; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.builder.BuildChainBuilder; +import io.quarkus.builder.BuildContext; +import io.quarkus.builder.BuildStep; +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; +import io.quarkus.vertx.http.deployment.RouteBuildItem; +import io.restassured.RestAssured; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; + +public class RuntimeRouteCandidateTest { + + private static final String APP_PROPS = "" + + "quarkus.http.root-path=/api\n" + + "route[1]=/build-time-route"; + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addAsResource(new StringAsset(APP_PROPS), "application.properties")) + .addBuildChainCustomizer(buildCustomizer()) + .overrideRuntimeConfigKey("route[1]", "/runtime-route"); + + static Consumer buildCustomizer() { + return new Consumer() { + @Override + public void accept(BuildChainBuilder builder) { + builder.addBuildStep(new BuildStep() { + @Override + public void execute(BuildContext context) { + context.produce(RouteBuildItem.builder() + .route(new PathSupplier()) + .handler(new MyHandler()) + .build()); + } + }).produces(RouteBuildItem.class) + .consumes(NonApplicationRootPathBuildItem.class) + .build(); + } + }; + } + + public static class MyHandler implements Handler { + @Override + public void handle(RoutingContext routingContext) { + routingContext.response() + .setStatusCode(200) + .end(routingContext.request().path()); + } + } + + @Test + public void testRouteCreatedFromRuntimeProperty() { + RestAssured.given().get("/runtime-route").then().statusCode(200).body(Matchers.equalTo("/api/runtime-route")); + RestAssured.given().get("/build-time-route").then().statusCode(404); + } + + public static class PathSupplier implements Supplier { + + @Override + public String get() { + return ConfigProvider.getConfig().getConfigValue("route[1]").getRawValue(); + } + } + +} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthBuildTimeConfig.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthBuildTimeConfig.java new file mode 100644 index 00000000000000..84160349b21004 --- /dev/null +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthBuildTimeConfig.java @@ -0,0 +1,38 @@ +package io.quarkus.vertx.http.runtime; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +/** + * Authentication mechanism information used for configuring HTTP auth + * instance for the deployment. + */ +@ConfigGroup +public class AuthBuildTimeConfig { + + /** + * If basic auth should be enabled. If both basic and form auth is enabled then basic auth will be enabled in silent mode. + * + * If no authentication mechanisms are configured basic auth is the default. + */ + @ConfigItem + public Optional basic; + + /** + * If form authentication is enabled. + */ + @ConfigItem(name = "form.enabled") + public boolean form; + + /** + * If this is true and credentials are present then a user will always be authenticated + * before the request progresses. + * + * If this is false then an attempt will only be made to authenticate the user if a permission + * check is performed or the current user is required for some other reason. + */ + @ConfigItem(defaultValue = "true") + public boolean proactive; +} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthConfig.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthConfig.java index 3e609d66f98257..399a8a126bf813 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthConfig.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/AuthConfig.java @@ -12,13 +12,6 @@ */ @ConfigGroup public class AuthConfig { - /** - * If basic auth should be enabled. If both basic and form auth is enabled then basic auth will be enabled in silent mode. - * - * If no authentication mechanisms are configured basic auth is the default. - */ - @ConfigItem - public Optional basic; /** * Form Auth config @@ -44,13 +37,4 @@ public class AuthConfig { @ConfigItem(name = "policy") public Map rolePolicy; - /** - * If this is true and credentials are present then a user will always be authenticated - * before the request progresses. - * - * If this is false then an attempt will only be made to authenticate the user if a permission - * check is performed or the current user is required for some other reason. - */ - @ConfigItem(defaultValue = "true") - public boolean proactive; } diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/FormAuthConfig.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/FormAuthConfig.java index e08e6595129ba6..b013fb1dca9ccb 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/FormAuthConfig.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/FormAuthConfig.java @@ -20,12 +20,6 @@ public enum CookieSameSite { NONE } - /** - * If form authentication is enabled. - */ - @ConfigItem - public boolean enabled; - /** * The login page. Redirect to login page can be disabled by setting `quarkus.http.auth.form.login-page=`. */ diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpBuildTimeConfig.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpBuildTimeConfig.java index 04438741785095..3d39bae9703d58 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpBuildTimeConfig.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpBuildTimeConfig.java @@ -24,7 +24,7 @@ public class HttpBuildTimeConfig { @ConvertWith(NormalizeRootHttpPathConverter.class) public String rootPath; - public AuthConfig auth; + public AuthBuildTimeConfig auth; /** * Configures the engine to require/request client authentication. diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java index e62490a3dddbef..58af4ccf01a29b 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java @@ -14,6 +14,8 @@ @ConfigRoot(phase = ConfigPhase.RUN_TIME) public class HttpConfiguration { + public AuthConfig auth; + /** * Enable the CORS filter. */ diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/RouteCandidate.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/RouteCandidate.java new file mode 100644 index 00000000000000..deec29278fd862 --- /dev/null +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/RouteCandidate.java @@ -0,0 +1,43 @@ +package io.quarkus.vertx.http.runtime; + +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Supplier; + +import io.vertx.ext.web.Route; +import io.vertx.ext.web.Router; + +/** + * Creates {@link Function} if {@link #path} underlying value + * is not null during runtime init. + */ +public class RouteCandidate implements Function { + + private Supplier path; + + public RouteCandidate() { + } + + public RouteCandidate(Supplier path) { + Objects.requireNonNull(path); + this.path = path; + } + + public Supplier getPath() { + return path; + } + + public void setPath(Supplier path) { + this.path = path; + } + + /* RUNTIME_INIT */ + @Override + public Route apply(Router router) { + final String resolvedPath = path.get(); + if (resolvedPath == null) { + return null; + } + return router.route(resolvedPath); + } +} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java index a3516d34f8d955..cdf61b435c879b 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java @@ -1088,6 +1088,13 @@ public void addRoute(RuntimeValue router, Function route, Route vr = route.apply(router.getValue()); + // routes prepared during the build time for runtime configuration + // properties are nullable if user decided to not configure the property + // please see class 'RouteCandidate' for more details + if (vr == null) { + return; + } + if (blocking == HandlerType.BLOCKING) { vr.blockingHandler(handler, false); } else if (blocking == HandlerType.FAILURE) { diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java index 6d4b707e542a5c..3ea510d7c51584 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; import java.util.Base64; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletionException; import java.util.function.BiConsumer; @@ -13,8 +14,7 @@ import org.jboss.logging.Logger; -import io.quarkus.arc.runtime.BeanContainer; -import io.quarkus.arc.runtime.BeanContainerListener; +import io.quarkus.arc.Arc; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; import io.quarkus.security.AuthenticationCompletionException; @@ -25,6 +25,7 @@ import io.quarkus.vertx.http.runtime.FormAuthConfig; import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; import io.quarkus.vertx.http.runtime.HttpConfiguration; +import io.quarkus.vertx.http.runtime.PolicyConfig; import io.smallrye.mutiny.CompositeException; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.subscription.UniSubscriber; @@ -209,14 +210,23 @@ public void handle(RoutingContext event) { }; } - public BeanContainerListener initPermissions(HttpBuildTimeConfig permissions, - Map> policies) { - return new BeanContainerListener() { - @Override - public void created(BeanContainer container) { - container.beanInstance(PathMatchingHttpSecurityPolicy.class).init(permissions, policies); + public void initPermissions( + Map> buildTimePolicies) { + var permissions = httpConfiguration.getValue().auth.permissions; + if (!permissions.isEmpty()) { + Map> policies = new HashMap<>(buildTimePolicies); + var rolePolicies = httpConfiguration.getValue().auth.rolePolicy; + for (Map.Entry e : rolePolicies.entrySet()) { + if (policies.containsKey(e.getKey())) { + throw new RuntimeException("Multiple HTTP security policies defined with name " + e.getKey()); + } + policies.put(e.getKey(), + new SupplierImpl<>(new RolesAllowedHttpSecurityPolicy(e.getValue().rolesAllowed))); } - }; + + PathMatchingHttpSecurityPolicy bean = Arc.container().instance(PathMatchingHttpSecurityPolicy.class).get(); + bean.init(buildTimeConfig, policies, permissions); + } } public Supplier setupFormAuth() { @@ -239,7 +249,7 @@ public FormAuthenticationMechanism get() { } else { key = httpConfiguration.getValue().encryptionKey.get(); } - FormAuthConfig form = buildTimeConfig.auth.form; + FormAuthConfig form = httpConfiguration.getValue().auth.form; PersistentLoginManager loginManager = new PersistentLoginManager(key, form.cookieName, form.timeout.toMillis(), form.newCookieInterval.toMillis(), form.httpOnlyCookie, form.cookieSameSite.name(), form.cookiePath.orElse(null)); @@ -270,8 +280,8 @@ public Supplier setupBasicAuth(HttpBuildTimeConfig buildTimeConfig) { return new Supplier() { @Override public BasicAuthenticationMechanism get() { - return new BasicAuthenticationMechanism(buildTimeConfig.auth.realm.orElse(null), - buildTimeConfig.auth.form.enabled); + return new BasicAuthenticationMechanism(httpConfiguration.getValue().auth.realm.orElse(null), + buildTimeConfig.auth.form); } }; } @@ -285,6 +295,16 @@ public MtlsAuthenticationMechanism get() { }; } + /* RUNTIME_INIT */ + public Supplier getFormPostLocation() { + return new Supplier() { + @Override + public String get() { + return httpConfiguration.getValue().auth.form.postLocation; + } + }; + } + /** * This handler resolves the identity, and will be mapped to the post location. Otherwise, * for lazy auth the post will not be evaluated if there is no security rule for the post location. diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/PathMatchingHttpSecurityPolicy.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/PathMatchingHttpSecurityPolicy.java index 52c2e0de186afd..78d772bcfa8dfc 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/PathMatchingHttpSecurityPolicy.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/PathMatchingHttpSecurityPolicy.java @@ -83,14 +83,16 @@ public Uni apply(CheckResult checkResult) { }); } - void init(HttpBuildTimeConfig config, Map> supplierMap) { + void init(HttpBuildTimeConfig config, Map> supplierMap, + Map permissions) { + Map permissionCheckers = new HashMap<>(); for (Map.Entry> i : supplierMap.entrySet()) { permissionCheckers.put(i.getKey(), i.getValue().get()); } Map> tempMap = new HashMap<>(); - for (Map.Entry entry : config.auth.permissions.entrySet()) { + for (Map.Entry entry : permissions.entrySet()) { HttpSecurityPolicy checker = permissionCheckers.get(entry.getValue().policy); if (checker == null) { throw new RuntimeException("Unable to find HTTP security policy " + entry.getValue().policy);