From 50125bce72a63e18d6e423dfa217d3809e08c500 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Wed, 28 Sep 2022 13:20:21 +0100 Subject: [PATCH] Restore the query when redirecting to the OIDC error path --- .../runtime/CodeAuthenticationMechanism.java | 42 +++++++++++++++---- .../io/quarkus/it/keycloak/TenantHttps.java | 5 ++- .../io/quarkus/it/keycloak/CodeFlowTest.java | 2 +- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java index 84576f9348c5f..68e53d0a981bd 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java @@ -153,17 +153,41 @@ public Uni apply(TenantConfigContext tenantContext) { LOG.debugf("Authentication has failed, error: %s, description: %s", error, errorDescription); if (oidcTenantConfig.authentication.errorPath.isPresent()) { - URI absoluteUri = URI.create(context.request().absoluteURI()); + Uni resolvedContext = resolver.resolveContext(context); + return resolvedContext.onItem() + .transformToUni(new Function>() { + @Override + public Uni apply(TenantConfigContext tenantContext) { + URI absoluteUri = URI.create(context.request().absoluteURI()); + + String userQuery = null; + + // This is an original redirect from IDP, check if the original request path and query need to be restored + CodeAuthenticationStateBean stateBean = getCodeAuthenticationBean(parsedStateCookieValue, + tenantContext); + if (stateBean != null && stateBean.getRestorePath() != null) { + String restorePath = stateBean.getRestorePath(); + int userQueryIndex = restorePath.indexOf("?"); + if (userQueryIndex >= 0 && userQueryIndex + 1 < restorePath.length()) { + userQuery = restorePath.substring(userQueryIndex + 1); + } + } - StringBuilder errorUri = new StringBuilder(buildUri(context, - isForceHttps(oidcTenantConfig), - absoluteUri.getAuthority(), - oidcTenantConfig.authentication.errorPath.get())); - errorUri.append('?').append(getRequestParametersAsQuery(absoluteUri, requestParams, oidcTenantConfig)); + StringBuilder errorUri = new StringBuilder(buildUri(context, + isForceHttps(oidcTenantConfig), + absoluteUri.getAuthority(), + oidcTenantConfig.authentication.errorPath.get())); + errorUri.append('?') + .append(getRequestParametersAsQuery(absoluteUri, requestParams, oidcTenantConfig)); + if (userQuery != null) { + errorUri.append('&').append(userQuery); + } - String finalErrorUri = errorUri.toString(); - LOG.debugf("Error URI: %s", finalErrorUri); - return Uni.createFrom().failure(new AuthenticationRedirectException(finalErrorUri)); + String finalErrorUri = errorUri.toString(); + LOG.debugf("Error URI: %s", finalErrorUri); + return Uni.createFrom().failure(new AuthenticationRedirectException(finalErrorUri)); + } + }); } else { LOG.error( "Authentication has failed but no error handler is found, completing the code flow with HTTP status 401"); diff --git a/integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantHttps.java b/integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantHttps.java index 4f752143d3e92..f06cffa5a4699 100644 --- a/integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantHttps.java +++ b/integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantHttps.java @@ -33,7 +33,8 @@ public String getTenantWithQuery(@QueryParam("code") String value) { @GET @Path("error") - public String getError(@QueryParam("error") String error, @QueryParam("error_description") String errorDescription) { - return "error: " + error + ", error_description: " + errorDescription; + public String getError(@QueryParam("error") String error, @QueryParam("error_description") String errorDescription, + @QueryParam("code") String value) { + return "code: " + value + ", error: " + error + ", error_description: " + errorDescription; } } diff --git a/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java b/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java index 0049d1d1eedc5..a808bf0c98a2f 100644 --- a/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java +++ b/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java @@ -148,7 +148,7 @@ public void testCodeFlowScopeErrorWithErrorPage() throws IOException { endpointErrorLocation = "http" + endpointErrorLocation.substring(5); HtmlPage page = webClient.getPage(URI.create(endpointErrorLocation).toURL()); - assertEquals("error: invalid_scope, error_description: Invalid scopes: unknown", + assertEquals("code: b, error: invalid_scope, error_description: Invalid scopes: unknown", page.getBody().asText()); webClient.getCookieManager().clearCookies(); }