Skip to content

Commit

Permalink
Merge pull request #43374 from sberyozkin/disabled_oidc_client_filter
Browse files Browse the repository at this point in the history
Update OIDC client filters to check if OIDC client feature is enabled
  • Loading branch information
sberyozkin authored Sep 20, 2024
2 parents 14af184 + 6092c24 commit b229e58
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<ClientWebApplicationException> {

@Override
public Response toResponse(ClientWebApplicationException t) {
return Response.status(t.getResponse().getStatus()).build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class NamedOidcClientFilterDevModeTest {
ProtectedResourceServiceAnnotationOidcClient.class,
ProtectedResourceServiceConfigPropertyOidcClient.class,
ProtectedResourceServiceCustomProviderConfigPropOidcClient.class,
OidcClientResource.class
OidcClientResource.class,
ClientWebApplicationExceptionMapper.class
};

@RegisterExtension
Expand All @@ -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"));
Expand All @@ -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"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,4 +18,10 @@ public class ProtectedResource {
public String principalName() {
return principal.getName();
}

@GET
@Path("/anonymous")
public String anonymousPrincipalName() {
return principal.getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ public interface ProtectedResourceServiceAnnotationOidcClient {

@GET
String getUserName();

@GET
@Path("/anonymous")
String getAnonymousUserName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ public interface ProtectedResourceServiceConfigPropertyOidcClient {

@GET
String getUserName();

@GET
@Path("/anonymous")
String getAnonymousUserName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ public interface ProtectedResourceServiceCustomProviderConfigPropOidcClient {

@GET
String getUserName();

@GET
@Path("/anonymous")
String getAnonymousUserName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<OidcClient> initializedClient = client();
if (initializedClient.isEmpty()) {
Optional<String> clientId = Objects.requireNonNull(clientId(), "clientId must not be null");
Expand All @@ -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<Tokens> 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<String> clientId = clientId();
Expand All @@ -66,6 +85,9 @@ public Uni<Tokens> getTokens() {
}

public Tokens awaitTokens() {
if (isClientFeatureDisabled()) {
throw new IllegalStateException("OIDC client feature is disabled with `quarkus.oidc-client.enabled=false`.");
}
return getTokens().await().indefinitely();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down

0 comments on commit b229e58

Please sign in to comment.