From a17b30a4f93f90992ae4822f6f9d3d6a8a8bd10b Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 13 Aug 2024 18:16:27 +0100 Subject: [PATCH] Add http root to OIDC back channel logout handlers --- .../java/io/quarkus/oidc/OidcTenantConfig.java | 2 ++ .../oidc/runtime/BackChannelLogoutHandler.java | 18 ++++++++++++++++-- .../runtime/DefaultTenantConfigResolver.java | 6 ++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java index 0c20982f42061..290121ce29559 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java @@ -424,6 +424,8 @@ public void setFrontchannel(Frontchannel frontchannel) { public static class Backchannel { /** * The relative path of the Back-Channel Logout endpoint at the application. + * It must start with the forward slash '/', for example, '/back-channel-logout'. + * This value is always resolved relative to 'quarkus.http.root-path'. */ @ConfigItem public Optional path = Optional.empty(); diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/BackChannelLogoutHandler.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/BackChannelLogoutHandler.java index f3047ddb20521..f66c5899e834f 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/BackChannelLogoutHandler.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/BackChannelLogoutHandler.java @@ -13,6 +13,7 @@ import io.quarkus.oidc.OidcTenantConfig; import io.quarkus.oidc.SecurityEvent; import io.quarkus.oidc.SecurityEvent.Type; +import io.quarkus.oidc.common.runtime.OidcCommonUtils; import io.quarkus.oidc.common.runtime.OidcConstants; import io.quarkus.security.spi.runtime.SecurityEventHelper; import io.vertx.core.Handler; @@ -24,6 +25,7 @@ public class BackChannelLogoutHandler { private static final Logger LOG = Logger.getLogger(BackChannelLogoutHandler.class); + private static final String SLASH = "/"; @Inject DefaultTenantConfigResolver resolver; @@ -44,7 +46,8 @@ public void setup(@Observes Router router) { private void addRoute(Router router, OidcTenantConfig oidcTenantConfig) { if (oidcTenantConfig.isTenantEnabled() && oidcTenantConfig.logout.backchannel.path.isPresent()) { - router.route(oidcTenantConfig.logout.backchannel.path.get()).handler(new RouteHandler(oidcTenantConfig)); + router.route(getRootPath() + oidcTenantConfig.logout.backchannel.path.get()) + .handler(new RouteHandler(oidcTenantConfig)); } } @@ -160,7 +163,18 @@ private TenantConfigContext getTenantConfigContext(RoutingContext context) { private boolean isMatchingTenant(String requestPath, TenantConfigContext tenant) { return tenant.oidcConfig.isTenantEnabled() && tenant.oidcConfig.getTenantId().get().equals(oidcTenantConfig.getTenantId().get()) - && requestPath.equals(tenant.oidcConfig.logout.backchannel.path.orElse(null)); + && requestPath.equals(getRootPath() + tenant.oidcConfig.logout.backchannel.path.orElse(null)); } } + + private String getRootPath() { + // Prepend '/' if it is not present + String rootPath = OidcCommonUtils.prependSlash(resolver.getRootPath()); + // Strip trailing '/' if the length is > 1 + if (rootPath.length() > 1 && rootPath.endsWith("/")) { + rootPath = rootPath.substring(rootPath.length() - 1); + } + // if it is only '/' then return an empty value + return SLASH.equals(rootPath) ? "" : rootPath; + } } diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java index d679739d539b8..28d79053b5132 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTenantConfigResolver.java @@ -51,6 +51,7 @@ public class DefaultTenantConfigResolver { private final TenantConfigBean tenantConfigBean; private final TenantResolver[] staticTenantResolvers; private final boolean annotationBasedTenantResolutionEnabled; + private final String rootPath; @Inject Instance tenantConfigResolver; @@ -86,6 +87,7 @@ public class DefaultTenantConfigResolver { this.staticTenantResolvers = prepareStaticTenantResolvers(tenantConfigBean, rootPath, tenantResolverInstance, resolveTenantsWithIssuer, new DefaultStaticTenantResolver()); this.annotationBasedTenantResolutionEnabled = Boolean.getBoolean(OidcUtils.ANNOTATION_BASED_TENANT_RESOLUTION_ENABLED); + this.rootPath = rootPath; } @PostConstruct @@ -414,6 +416,10 @@ public OidcTenantConfig getResolvedConfig(String sessionTenantId) { return null; } + public String getRootPath() { + return rootPath; + } + private static final class IssuerBasedTenantResolver implements TenantResolver { private final TenantConfigContext[] tenantConfigContexts;