diff --git a/extensions/oidc/deployment/src/test/java/io/quarkus/oidc/test/UserInfoRequiredWithoutUserPath.java b/extensions/oidc/deployment/src/test/java/io/quarkus/oidc/test/UserInfoRequiredWithoutUserPath.java new file mode 100644 index 00000000000000..b1376ac36bb11d --- /dev/null +++ b/extensions/oidc/deployment/src/test/java/io/quarkus/oidc/test/UserInfoRequiredWithoutUserPath.java @@ -0,0 +1,50 @@ +package io.quarkus.oidc.test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.runtime.configuration.ConfigurationException; +import io.quarkus.test.QuarkusUnitTest; + +public class UserInfoRequiredWithoutUserPath { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addAsResource(new StringAsset( + "quarkus.oidc.authentication.id-token-required=false\n" + + "quarkus.oidc.authorization-path=authorize\n" + + "quarkus.oidc.token-path=token\n" + + "quarkus.oidc.application-type=web-app\n" + + "quarkus.oidc.authentication.verify-access-token=false\n" + + "quarkus.oidc.discovery-enabled=false\n"), + "application.properties")) + .assertException(t -> { + Throwable e = t; + ConfigurationException te = null; + while (e != null) { + if (e instanceof ConfigurationException) { + te = (ConfigurationException) e; + break; + } + e = e.getCause(); + } + assertNotNull(te); + // assert UserInfo is required + assertTrue( + te.getMessage() + .contains("UserInfo is required but 'quarkus.oidc.user-info-path' is not configured."), + te.getMessage()); + }); + + @Test + public void test() { + Assertions.fail(); + } + +} diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java index f7d86b2525ba6a..3f10ffc72b0ae6 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java @@ -226,6 +226,11 @@ private Uni createTenantContext(Vertx vertx, OidcTenantConf Set.of("quarkus.oidc.jwks-path", "quarkus.oidc.introspection-path")); } } + if (oidcConfig.authentication.userInfoRequired.orElse(false) && !oidcConfig.userInfoPath.isPresent()) { + throw new ConfigurationException( + "UserInfo is required but 'quarkus.oidc.user-info-path' is not configured.", + Set.of("quarkus.oidc.user-info-path")); + } } if (OidcUtils.isServiceApp(oidcConfig)) { @@ -450,6 +455,12 @@ public Uni apply(OidcConfigurationMetadata metadata, Throwab "The application supports RP-Initiated Logout but the OpenID Provider does not advertise the end_session_endpoint")); } } + if (oidcConfig.authentication.userInfoRequired.orElse(false) && metadata.getUserInfoUri() == null) { + client.close(); + return Uni.createFrom().failure(new ConfigurationException( + "UserInfo is required but the OpenID Provider UserInfo endpoint is not configured." + + " Use 'quarkus.oidc.user-info-path' if the discovery is disabled.")); + } return Uni.createFrom().item(new OidcProviderClient(client, metadata, oidcConfig)); }