From 6092c247b695f03a7da2b43dd519eab393a0cfe6 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Wed, 18 Sep 2024 16:06:27 +0100 Subject: [PATCH] Update OIDC client filters to check if OIDC client feature is enabled --- .../AbstractOidcClientRequestFilter.java | 5 ++ .../ClientWebApplicationExceptionMapper.java | 17 +++++++ .../NamedOidcClientFilterDevModeTest.java | 51 ++++++++++++++++++- .../reactive/filter/OidcClientResource.java | 18 +++++++ .../reactive/filter/ProtectedResource.java | 9 ++-- ...edResourceServiceAnnotationOidcClient.java | 4 ++ ...sourceServiceConfigPropertyOidcClient.java | 4 ++ ...iceCustomProviderConfigPropOidcClient.java | 4 ++ ...ion-oidc-client-reactive-filter.properties | 2 + ...stractOidcClientRequestReactiveFilter.java | 5 ++ .../runtime/AbstractTokensProducer.java | 22 ++++++++ .../runtime/OidcClientBuildTimeConfig.java | 3 +- 12 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ClientWebApplicationExceptionMapper.java diff --git a/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java b/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java index 458fa15740778..fb16adec18dcd 100644 --- a/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java +++ b/extensions/oidc-client-filter/runtime/src/main/java/io/quarkus/oidc/client/filter/runtime/AbstractOidcClientRequestFilter.java @@ -21,6 +21,11 @@ public AbstractOidcClientRequestFilter() { @Override public void filter(ClientRequestContext requestContext) throws IOException { + if (isClientFeatureDisabled()) { + LOG.debug("OIDC client filter can not acquire and propagate tokens because " + + "OIDC client is disabled with `quarkus.oidc-client.enabled=false`"); + return; + } try { final String accessToken = getAccessToken(); requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, BEARER_SCHEME_WITH_SPACE + accessToken); diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ClientWebApplicationExceptionMapper.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ClientWebApplicationExceptionMapper.java new file mode 100644 index 0000000000000..991f69c687070 --- /dev/null +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ClientWebApplicationExceptionMapper.java @@ -0,0 +1,17 @@ +package io.quarkus.oidc.client.reactive.filter; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.ext.Provider; + +import org.jboss.resteasy.reactive.ClientWebApplicationException; + +@Provider +public class ClientWebApplicationExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(ClientWebApplicationException t) { + return Response.status(t.getResponse().getStatus()).build(); + } + +} diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/NamedOidcClientFilterDevModeTest.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/NamedOidcClientFilterDevModeTest.java index ef401cbe4d80d..6612e1cc8084c 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/NamedOidcClientFilterDevModeTest.java +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/NamedOidcClientFilterDevModeTest.java @@ -18,7 +18,8 @@ public class NamedOidcClientFilterDevModeTest { ProtectedResourceServiceAnnotationOidcClient.class, ProtectedResourceServiceConfigPropertyOidcClient.class, ProtectedResourceServiceCustomProviderConfigPropOidcClient.class, - OidcClientResource.class + OidcClientResource.class, + ClientWebApplicationExceptionMapper.class }; @RegisterExtension @@ -31,8 +32,47 @@ public class NamedOidcClientFilterDevModeTest { public void testGerUserConfigPropertyAndAnnotation() { // test OidcClientFilter with OidcClient selected via annotation or config-property + // Client feature is disabled // OidcClient selected via @OidcClient("clientName") RestAssured.when().get("/oidc-client/annotation/user-name") + .then() + .statusCode(401); + + RestAssured.when().get("/oidc-client/annotation/anonymous-user-name") + .then() + .statusCode(204) + .body(equalTo("")); + + // @OidcClientFilter: OidcClient selected via `quarkus.oidc-client-filter.client-name=config-property` + RestAssured.when().get("/oidc-client/config-property/user-name") + .then() + .statusCode(401); + + RestAssured.when().get("/oidc-client/config-property/anonymous-user-name") + .then() + .statusCode(204) + .body(equalTo("")); + + // @RegisterProvider(OidcClientRequestReactiveFilter.class): OidcClient selected via `quarkus.oidc-client-filter.client-name=config-property` + RestAssured.when().get("/oidc-client/custom-provider-config-property/user-name") + .then() + .statusCode(401); + + RestAssured.when().get("/oidc-client/custom-provider-config-property/anonymous-user-name") + .then() + .statusCode(204) + .body(equalTo("")); + + test.modifyResourceFile("application.properties", s -> s.replace(".enabled=false", ".enabled=true")); + + // Client feature is enabled + // OidcClient selected via @OidcClient("clientName") + RestAssured.when().get("/oidc-client/annotation/user-name") + .then() + .statusCode(200) + .body(equalTo("jdoe")); + + RestAssured.when().get("/oidc-client/annotation/anonymous-user-name") .then() .statusCode(200) .body(equalTo("jdoe")); @@ -43,11 +83,20 @@ public void testGerUserConfigPropertyAndAnnotation() { .statusCode(200) .body(equalTo("alice")); + RestAssured.when().get("/oidc-client/config-property/anonymous-user-name") + .then() + .statusCode(200) + .body(equalTo("alice")); + // @RegisterProvider(OidcClientRequestReactiveFilter.class): OidcClient selected via `quarkus.oidc-client-filter.client-name=config-property` RestAssured.when().get("/oidc-client/custom-provider-config-property/user-name") .then() .statusCode(200) .body(equalTo("alice")); + RestAssured.when().get("/oidc-client/custom-provider-config-property/anonymous-user-name") + .then() + .statusCode(200) + .body(equalTo("alice")); } } diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/OidcClientResource.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/OidcClientResource.java index 559047ef13dea..28c8972fecc05 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/OidcClientResource.java +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/OidcClientResource.java @@ -27,15 +27,33 @@ public String annotationUserName() { return protectedResourceServiceAnnotationOidcClient.getUserName(); } + @GET + @Path("/annotation/anonymous-user-name") + public String annotationAnonymousUserName() { + return protectedResourceServiceAnnotationOidcClient.getAnonymousUserName(); + } + @GET @Path("/config-property/user-name") public String configPropertyUserName() { return protectedResourceServiceConfigPropertyOidcClient.getUserName(); } + @GET + @Path("/config-property/anonymous-user-name") + public String configPropertyAnonymousUserName() { + return protectedResourceServiceConfigPropertyOidcClient.getAnonymousUserName(); + } + @GET @Path("/custom-provider-config-property/user-name") public String customProviderConfigPropertyUserName() { return protectedResourceServiceCustomProviderConfigPropOidcClient.getUserName(); } + + @GET + @Path("/custom-provider-config-property/anonymous-user-name") + public String customProviderConfigPropertyAnonymousUserName() { + return protectedResourceServiceCustomProviderConfigPropOidcClient.getAnonymousUserName(); + } } diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResource.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResource.java index 23ddd9ef09764..4bc4188738abf 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResource.java +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResource.java @@ -7,10 +7,7 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; -import io.quarkus.security.Authenticated; - @Path("/protected") -@Authenticated public class ProtectedResource { @Inject @@ -21,4 +18,10 @@ public class ProtectedResource { public String principalName() { return principal.getName(); } + + @GET + @Path("/anonymous") + public String anonymousPrincipalName() { + return principal.getName(); + } } diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceAnnotationOidcClient.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceAnnotationOidcClient.java index eda0b6c579174..a09216a1252c1 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceAnnotationOidcClient.java +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceAnnotationOidcClient.java @@ -14,4 +14,8 @@ public interface ProtectedResourceServiceAnnotationOidcClient { @GET String getUserName(); + + @GET + @Path("/anonymous") + String getAnonymousUserName(); } diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceConfigPropertyOidcClient.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceConfigPropertyOidcClient.java index ee77cac550886..b5827d0ad7f74 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceConfigPropertyOidcClient.java +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceConfigPropertyOidcClient.java @@ -14,4 +14,8 @@ public interface ProtectedResourceServiceConfigPropertyOidcClient { @GET String getUserName(); + + @GET + @Path("/anonymous") + String getAnonymousUserName(); } diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceCustomProviderConfigPropOidcClient.java b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceCustomProviderConfigPropOidcClient.java index 1e1a82b75042c..bb5f3b1f9476a 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceCustomProviderConfigPropOidcClient.java +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/java/io/quarkus/oidc/client/reactive/filter/ProtectedResourceServiceCustomProviderConfigPropOidcClient.java @@ -13,4 +13,8 @@ public interface ProtectedResourceServiceCustomProviderConfigPropOidcClient { @GET String getUserName(); + + @GET + @Path("/anonymous") + String getAnonymousUserName(); } diff --git a/extensions/oidc-client-reactive-filter/deployment/src/test/resources/application-oidc-client-reactive-filter.properties b/extensions/oidc-client-reactive-filter/deployment/src/test/resources/application-oidc-client-reactive-filter.properties index ddd63e62e4764..821feda2d2dcb 100644 --- a/extensions/oidc-client-reactive-filter/deployment/src/test/resources/application-oidc-client-reactive-filter.properties +++ b/extensions/oidc-client-reactive-filter/deployment/src/test/resources/application-oidc-client-reactive-filter.properties @@ -2,6 +2,8 @@ quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/ quarkus.oidc.client-id=quarkus-service-app quarkus.oidc.credentials.secret=secret +quarkus.oidc-client.enabled=false + quarkus.rest-client-oidc-filter.client-name=config-property quarkus.oidc-client.config-property.auth-server-url=${quarkus.oidc.auth-server-url} quarkus.oidc-client.config-property.client-id=${quarkus.oidc.client-id} diff --git a/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java b/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java index 5bff7d719403d..8fb9843a053a8 100644 --- a/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java +++ b/extensions/oidc-client-reactive-filter/runtime/src/main/java/io/quarkus/oidc/client/reactive/filter/runtime/AbstractOidcClientRequestReactiveFilter.java @@ -26,6 +26,11 @@ protected void initTokens() { @Override public void filter(ResteasyReactiveClientRequestContext requestContext) { + if (isClientFeatureDisabled()) { + LOG.debug("OIDC client filter can not acquire and propagate tokens because " + + "OIDC client is disabled with `quarkus.oidc-client.enabled=false`"); + return; + } requestContext.suspend(); super.getTokens().subscribe().with(new Consumer<>() { diff --git a/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/AbstractTokensProducer.java b/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/AbstractTokensProducer.java index 7e2f14f80566d..0c7f8d948c57d 100644 --- a/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/AbstractTokensProducer.java +++ b/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/AbstractTokensProducer.java @@ -24,11 +24,18 @@ public abstract class AbstractTokensProducer { @Inject public OidcClientsConfig oidcClientsConfig; + @Inject + public OidcClientBuildTimeConfig oidcClientBuildTimeConfig; final TokensHelper tokensHelper = new TokensHelper(); @PostConstruct public void init() { + if (isClientFeatureDisabled()) { + LOG.debug("OIDC client is disabled with `quarkus.oidc-client.enabled=false`," + + " skipping the token producer initialization"); + return; + } Optional initializedClient = client(); if (initializedClient.isEmpty()) { Optional clientId = Objects.requireNonNull(clientId(), "clientId must not be null"); @@ -49,13 +56,25 @@ public void init() { initTokens(); } + protected boolean isClientFeatureDisabled() { + return !oidcClientBuildTimeConfig.enabled; + } + protected void initTokens() { + if (isClientFeatureDisabled()) { + throw new IllegalStateException("OIDC client feature is disabled with `quarkus.oidc-client.enabled=false`" + + " but the initTokens() method is called."); + } if (earlyTokenAcquisition) { tokensHelper.initTokens(oidcClient, additionalParameters()); } } public Uni getTokens() { + if (isClientFeatureDisabled()) { + throw new IllegalStateException("OIDC client feature is disabled with `quarkus.oidc-client.enabled=false`" + + " but the getTokens() method is called."); + } final boolean forceNewTokens = isForceNewTokens(); if (forceNewTokens) { final Optional clientId = clientId(); @@ -66,6 +85,9 @@ public Uni getTokens() { } public Tokens awaitTokens() { + if (isClientFeatureDisabled()) { + throw new IllegalStateException("OIDC client feature is disabled with `quarkus.oidc-client.enabled=false`."); + } return getTokens().await().indefinitely(); } diff --git a/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientBuildTimeConfig.java b/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientBuildTimeConfig.java index cf25a43c52c91..a8dc58b35fdfb 100644 --- a/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientBuildTimeConfig.java +++ b/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientBuildTimeConfig.java @@ -1,12 +1,13 @@ package io.quarkus.oidc.client.runtime; import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; /** * Build time configuration for OIDC client. */ -@ConfigRoot +@ConfigRoot(name = "oidc-client", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) public class OidcClientBuildTimeConfig { /** * If the OIDC client extension is enabled.