diff --git a/docs/src/main/asciidoc/se/security/introduction.adoc b/docs/src/main/asciidoc/se/security/introduction.adoc index 42e2d370734..e4468ccdb03 100644 --- a/docs/src/main/asciidoc/se/security/introduction.adoc +++ b/docs/src/main/asciidoc/se/security/introduction.adoc @@ -56,6 +56,8 @@ Helidon Security provides authentication, authorization, and auditing for your H logger called "AUDIT" (may be overridden through configuration). AuditProvider SPI may be implemented to support other auditing options. +Each feature is implemented with the help of "xref:providers.adoc[Security Providers]". + Security module is quite HTTP centric (as most common use cases are related to HTTP REST), though it is not HTTP specific (the security module may be used to secure even other transports, such as JMS, Kafka messages etc. if an appropriate @@ -116,6 +118,13 @@ include::{sourcedir}/se/security/IntroductionSnippets.java[tag=snippet_3, indent ---- <1> Uses `io.helidon.Config` +As mentioned above, security features are implemented through providers, which are configured under key +`security.providers`. Each element of the list is one security provider. The key of the provider must match +its config key (as documented in xref:providers.adoc[Security Providers] for each supported provider). + +A key `enabled` can be used for each provider to provide fine control of which providers are enabled/disabled, for example +to support different setup in testing and in production environments. + [source,yaml] .Security from configuration - application.yaml ---- diff --git a/security/security/src/main/java/io/helidon/security/Security.java b/security/security/src/main/java/io/helidon/security/Security.java index 4eff081ebe9..31670f56beb 100644 --- a/security/security/src/main/java/io/helidon/security/Security.java +++ b/security/security/src/main/java/io/helidon/security/Security.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023 Oracle and/or its affiliates. + * Copyright (c) 2018, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1082,6 +1082,22 @@ private void providerFromConfig(Map configKeyTo Map classNameToService, String knownKeys, Config pConf) { + boolean enabled = pConf.get("enabled").asBoolean().orElse(true); + if (!enabled) { + // this provider is marked as disabled, we will ignore it + // this is checking the top level provider configuration (see below check for provider specific) + // this section check (example): + /* + security.providers: + - type: "some-type + enabled: false + */ + if (LOGGER.isLoggable(System.Logger.Level.TRACE)) { + LOGGER.log(System.Logger.Level.TRACE, "Provider with key: " + pConf.key() + " is disabled"); + } + return; + } + AtomicReference service = new AtomicReference<>(); AtomicReference providerSpecific = new AtomicReference<>(); @@ -1111,6 +1127,25 @@ private void providerFromConfig(Map configKeyTo } String name = resolveProviderName(pConf, className, providerSpecificConfig, providerService); + + if (providerSpecificConfig != null && !providerSpecificConfig.get("enabled") + .asBoolean() + .orElse(true)) { + // this provider is marked as disabled, we will ignore it + // this is within the provider specific configuration, to support both simple lists (checked above) + // and nested provider configuration; this section check (example): + /* + security.providers: + - oidc: + enabled: false + */ + + if (LOGGER.isLoggable(System.Logger.Level.TRACE)) { + LOGGER.log(System.Logger.Level.TRACE, "Provider: " + name + " is disabled"); + } + return; + } + boolean isAuthn = pConf.get("is-authentication-provider").asBoolean().orElse(true); boolean isAuthz = pConf.get("is-authorization-provider").asBoolean().orElse(true); boolean isClientSec = pConf.get("is-client-security-provider").asBoolean().orElse(true); diff --git a/tests/integration/mp-gh-8495/pom.xml b/tests/integration/mp-gh-8495/pom.xml new file mode 100644 index 00000000000..74081cddfb2 --- /dev/null +++ b/tests/integration/mp-gh-8495/pom.xml @@ -0,0 +1,68 @@ + + + + + io.helidon.tests.integration + helidon-tests-integration + 4.0.0-SNAPSHOT + + 4.0.0 + + helidon-tests-integration-mp-gh-8495 + Helidon Tests Integration MP GH 8495 + Reproducer for Github issue #8495 - SecurityCdiExtension fails with Oidc + + + + io.helidon.microprofile.server + helidon-microprofile-server + + + io.helidon.microprofile + helidon-microprofile-oidc + + + io.helidon.microprofile + helidon-microprofile-security + + + io.helidon.logging + helidon-logging-jul + runtime + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.hamcrest + hamcrest-all + test + + + io.helidon.microprofile.testing + helidon-microprofile-testing-junit5 + test + + + \ No newline at end of file diff --git a/tests/integration/mp-gh-8495/src/main/java/io/helidon/tests/integration/gh8495/Gh8495Resource.java b/tests/integration/mp-gh-8495/src/main/java/io/helidon/tests/integration/gh8495/Gh8495Resource.java new file mode 100644 index 00000000000..78349574873 --- /dev/null +++ b/tests/integration/mp-gh-8495/src/main/java/io/helidon/tests/integration/gh8495/Gh8495Resource.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.tests.integration.gh8495; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/greet") +public class Gh8495Resource { + @GET + @Produces(MediaType.TEXT_PLAIN) + public String getDefaultMessage() { + return "Hello World!"; + } +} diff --git a/tests/integration/mp-gh-8495/src/main/resources/META-INF/beans.xml b/tests/integration/mp-gh-8495/src/main/resources/META-INF/beans.xml new file mode 100644 index 00000000000..52f89a20d18 --- /dev/null +++ b/tests/integration/mp-gh-8495/src/main/resources/META-INF/beans.xml @@ -0,0 +1,25 @@ + + + + diff --git a/tests/integration/mp-gh-8495/src/main/resources/application.yaml b/tests/integration/mp-gh-8495/src/main/resources/application.yaml new file mode 100644 index 00000000000..4e4e355009d --- /dev/null +++ b/tests/integration/mp-gh-8495/src/main/resources/application.yaml @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +security: + providers: + - oidc: + enabled: false diff --git a/tests/integration/mp-gh-8495/src/main/resources/logging.properties b/tests/integration/mp-gh-8495/src/main/resources/logging.properties new file mode 100644 index 00000000000..e50b6d44f81 --- /dev/null +++ b/tests/integration/mp-gh-8495/src/main/resources/logging.properties @@ -0,0 +1,23 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +handlers=io.helidon.logging.jul.HelidonConsoleHandler +java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n + +.level=WARNING + +io.helidon.level=INFO +io.helidon.security.level=FINEST \ No newline at end of file diff --git a/tests/integration/mp-gh-8495/src/test/java/io/helidon/tests/integration/gh8495/Gh8495Test.java b/tests/integration/mp-gh-8495/src/test/java/io/helidon/tests/integration/gh8495/Gh8495Test.java new file mode 100644 index 00000000000..401d1f2768c --- /dev/null +++ b/tests/integration/mp-gh-8495/src/test/java/io/helidon/tests/integration/gh8495/Gh8495Test.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.tests.integration.gh8495; + +import io.helidon.microprofile.testing.junit5.HelidonTest; + +import jakarta.inject.Inject; +import jakarta.ws.rs.client.WebTarget; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@HelidonTest +public class Gh8495Test { + private final WebTarget target; + + @Inject + public Gh8495Test(WebTarget target) { + this.target = target; + } + + @Test + public void testServerStarted() { + String response = target + .path("/greet") + .request() + .get(String.class); + + assertThat(response, is("Hello World!")); + } +} diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml index 879de465fc5..10449e54adf 100644 --- a/tests/integration/pom.xml +++ b/tests/integration/pom.xml @@ -54,6 +54,7 @@ mp-gh-4654 mp-gh-5328 mp-gh-8478 + mp-gh-8495 mp-graphql mp-security-client mp-ws-services