From 2755d4b0ef42fa7f686b3cd2debe6d0793abdd32 Mon Sep 17 00:00:00 2001 From: Farah Juma Date: Wed, 1 May 2024 15:59:10 -0400 Subject: [PATCH 1/3] [ELY-2340] Rename an OIDC test method --- .../wildfly/security/http/oidc/OidcTest.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java index 7b211c9e38..a53f596c8f 100644 --- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java @@ -132,13 +132,13 @@ public void testWrongPassword() throws Exception { @Test public void testWrongAuthServerUrl() throws Exception { - loginToAppMultiTenancy(getOidcConfigurationInputStream(CLIENT_SECRET, "http://fakeauthserver/auth"), KeycloakConfiguration.ALICE, + performAuthentication(getOidcConfigurationInputStream(CLIENT_SECRET, "http://fakeauthserver/auth"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, false, -1, null, null); } @Test public void testWrongClientSecret() throws Exception { - loginToAppMultiTenancy(getOidcConfigurationInputStream("WRONG_CLIENT_SECRET"), KeycloakConfiguration.ALICE, + performAuthentication(getOidcConfigurationInputStream("WRONG_CLIENT_SECRET"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_FORBIDDEN, null,"Forbidden"); } @@ -149,19 +149,19 @@ public void testMissingRequiredConfigurationOption() { @Test public void testSucessfulAuthenticationWithAuthServerUrl() throws Exception { - loginToAppMultiTenancy(getOidcConfigurationInputStream(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, + performAuthentication(getOidcConfigurationInputStream(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT); } @Test public void testSucessfulAuthenticationWithProviderUrl() throws Exception { - loginToAppMultiTenancy(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT); } @Test public void testSucessfulAuthenticationWithProviderUrlTrailingSlash() throws Exception { - loginToAppMultiTenancy(getOidcConfigurationInputStreamWithProviderUrlTrailingSlash(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, + performAuthentication(getOidcConfigurationInputStreamWithProviderUrlTrailingSlash(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT); } @@ -171,20 +171,20 @@ public void testSucessfulAuthenticationWithEnvironmentVariableExpression() throw String providerUrlEnv = System.getenv("OIDC_PROVIDER_URL_ENV"); assertEquals(oidcProviderUrl, providerUrlEnv); - loginToAppMultiTenancy(getOidcConfigurationInputStreamWithEnvironmentVariableExpression(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, + performAuthentication(getOidcConfigurationInputStreamWithEnvironmentVariableExpression(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT); } @Test public void testSucessfulAuthenticationWithSystemPropertyExpression() throws Exception { - loginToAppMultiTenancy(getOidcConfigurationInputStreamWithSystemPropertyExpression(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, + performAuthentication(getOidcConfigurationInputStreamWithSystemPropertyExpression(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT); } @Test public void testTokenSignatureAlgorithm() throws Exception { // keycloak uses RS256 - loginToAppMultiTenancy(getOidcConfigurationInputStreamWithTokenSignatureAlgorithm(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, + performAuthentication(getOidcConfigurationInputStreamWithTokenSignatureAlgorithm(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT); } @@ -363,8 +363,8 @@ private void testNonExistingUser(String username, String password, String tenant assertTrue(page.getBody().asText().contains("Invalid username or password")); } - private void loginToAppMultiTenancy(InputStream oidcConfig, String username, String password, boolean loginToKeycloak, - int expectedDispatcherStatusCode, String expectedLocation, String clientPageText) throws Exception { + private void performAuthentication(InputStream oidcConfig, String username, String password, boolean loginToKeycloak, + int expectedDispatcherStatusCode, String expectedLocation, String clientPageText) throws Exception { try { Map props = new HashMap<>(); OidcClientConfiguration oidcClientConfiguration = OidcClientConfigurationBuilder.build(oidcConfig); From 949c04ec6ae3139ced83c39244a9712c1d102300 Mon Sep 17 00:00:00 2001 From: Farah Juma Date: Wed, 1 May 2024 16:07:48 -0400 Subject: [PATCH 2/3] [ELY-2340] Move some test methods to OidcBaseTest --- .../security/http/oidc/BearerTest.java | 2 +- .../security/http/oidc/OidcBaseTest.java | 48 +++++++++++++++++++ .../wildfly/security/http/oidc/OidcTest.java | 42 ---------------- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/BearerTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/BearerTest.java index 1aacbe3239..18c4b2f087 100644 --- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/BearerTest.java +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/BearerTest.java @@ -488,7 +488,7 @@ private InputStream getOidcConfigurationInputStream(String authServerUrl) { return new ByteArrayInputStream(oidcConfig.getBytes(StandardCharsets.UTF_8)); } - private InputStream getOidcConfigurationInputStreamWithProviderUrl() { + protected InputStream getOidcConfigurationInputStreamWithProviderUrl() { String oidcConfig = "{\n" + " \"client-id\" : \"" + BEARER_ONLY_CLIENT_ID + "\",\n" + " \"provider-url\" : \"" + KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/" + TEST_REALM + "\",\n" + diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java index cee8c1b11e..79ac806d56 100644 --- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java @@ -21,9 +21,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.wildfly.security.http.oidc.Oidc.OIDC_NAME; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -49,6 +54,7 @@ import org.wildfly.security.jose.util.JsonSerialization; import com.gargoylesoftware.htmlunit.SilentCssErrorHandler; +import com.gargoylesoftware.htmlunit.TextPage; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlInput; @@ -59,6 +65,7 @@ import okhttp3.mockwebserver.Dispatcher; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.QueueDispatcher; import okhttp3.mockwebserver.RecordedRequest; /** @@ -291,4 +298,45 @@ protected String getCookieString(HttpServerCookie cookie) { return header.toString(); } + protected void performAuthentication(InputStream oidcConfig, String username, String password, boolean loginToKeycloak, + int expectedDispatcherStatusCode, String expectedLocation, String clientPageText) throws Exception { + try { + Map props = new HashMap<>(); + OidcClientConfiguration oidcClientConfiguration = OidcClientConfigurationBuilder.build(oidcConfig); + assertEquals(OidcClientConfiguration.RelativeUrlsUsed.NEVER, oidcClientConfiguration.getRelativeUrls()); + + OidcClientContext oidcClientContext = new OidcClientContext(oidcClientConfiguration); + oidcFactory = new OidcMechanismFactory(oidcClientContext); + HttpServerAuthenticationMechanism mechanism = oidcFactory.createAuthenticationMechanism(OIDC_NAME, props, getCallbackHandler()); + + URI requestUri = new URI(getClientUrl()); + TestingHttpServerRequest request = new TestingHttpServerRequest(null, requestUri); + mechanism.evaluateRequest(request); + TestingHttpServerResponse response = request.getResponse(); + assertEquals(loginToKeycloak ? HttpStatus.SC_MOVED_TEMPORARILY : HttpStatus.SC_FORBIDDEN, response.getStatusCode()); + assertEquals(Status.NO_AUTH, request.getResult()); + + if (loginToKeycloak) { + client.setDispatcher(createAppResponse(mechanism, expectedDispatcherStatusCode, expectedLocation, clientPageText)); + TextPage page = loginToKeycloak(username, password, requestUri, response.getLocation(), + response.getCookies()).click(); + assertTrue(page.getContent().contains(clientPageText)); + } + } finally { + client.setDispatcher(new QueueDispatcher()); + } + } + + protected InputStream getOidcConfigurationInputStreamWithProviderUrl() { + String oidcConfig = "{\n" + + " \"resource\" : \"" + CLIENT_ID + "\",\n" + + " \"public-client\" : \"false\",\n" + + " \"provider-url\" : \"" + KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/" + TEST_REALM + "\",\n" + + " \"ssl-required\" : \"EXTERNAL\",\n" + + " \"credentials\" : {\n" + + " \"secret\" : \"" + CLIENT_SECRET + "\"\n" + + " }\n" + + "}"; + return new ByteArrayInputStream(oidcConfig.getBytes(StandardCharsets.UTF_8)); + } } \ No newline at end of file diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java index a53f596c8f..4716f78d6c 100644 --- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java @@ -363,35 +363,6 @@ private void testNonExistingUser(String username, String password, String tenant assertTrue(page.getBody().asText().contains("Invalid username or password")); } - private void performAuthentication(InputStream oidcConfig, String username, String password, boolean loginToKeycloak, - int expectedDispatcherStatusCode, String expectedLocation, String clientPageText) throws Exception { - try { - Map props = new HashMap<>(); - OidcClientConfiguration oidcClientConfiguration = OidcClientConfigurationBuilder.build(oidcConfig); - assertEquals(OidcClientConfiguration.RelativeUrlsUsed.NEVER, oidcClientConfiguration.getRelativeUrls()); - - OidcClientContext oidcClientContext = new OidcClientContext(oidcClientConfiguration); - oidcFactory = new OidcMechanismFactory(oidcClientContext); - HttpServerAuthenticationMechanism mechanism = oidcFactory.createAuthenticationMechanism(OIDC_NAME, props, getCallbackHandler()); - - URI requestUri = new URI(getClientUrl()); - TestingHttpServerRequest request = new TestingHttpServerRequest(null, requestUri); - mechanism.evaluateRequest(request); - TestingHttpServerResponse response = request.getResponse(); - assertEquals(loginToKeycloak ? HttpStatus.SC_MOVED_TEMPORARILY : HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - assertEquals(Status.NO_AUTH, request.getResult()); - - if (loginToKeycloak) { - client.setDispatcher(createAppResponse(mechanism, expectedDispatcherStatusCode, expectedLocation, clientPageText)); - TextPage page = loginToKeycloak(username, password, requestUri, response.getLocation(), - response.getCookies()).click(); - assertTrue(page.getContent().contains(clientPageText)); - } - } finally { - client.setDispatcher(new QueueDispatcher()); - } - } - private void performTenantRequestWithAuthServerUrl(String username, String password, String tenant, String otherTenant) throws Exception { performTenantRequest(username, password, tenant, otherTenant, true); } @@ -467,19 +438,6 @@ private InputStream getOidcConfigurationInputStream(String clientSecret, String return new ByteArrayInputStream(oidcConfig.getBytes(StandardCharsets.UTF_8)); } - private InputStream getOidcConfigurationInputStreamWithProviderUrl() { - String oidcConfig = "{\n" + - " \"resource\" : \"" + CLIENT_ID + "\",\n" + - " \"public-client\" : \"false\",\n" + - " \"provider-url\" : \"" + KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/" + TEST_REALM + "\",\n" + - " \"ssl-required\" : \"EXTERNAL\",\n" + - " \"credentials\" : {\n" + - " \"secret\" : \"" + CLIENT_SECRET + "\"\n" + - " }\n" + - "}"; - return new ByteArrayInputStream(oidcConfig.getBytes(StandardCharsets.UTF_8)); - } - private InputStream getOidcConfigurationInputStreamWithEnvironmentVariableExpression() { String oidcConfig = "{\n" + " \"resource\" : \"" + CLIENT_ID + "\",\n" + From 5aba217507c0ffe77bc91d6069076088498e77f1 Mon Sep 17 00:00:00 2001 From: Farah Juma Date: Wed, 1 May 2024 16:17:33 -0400 Subject: [PATCH 3/3] [ELY-2340] Add the ability to allow query params in redirect URIs via a new system property --- .../org/wildfly/security/http/oidc/Oidc.java | 2 + .../http/oidc/OidcRequestAuthenticator.java | 21 ++++- .../security/http/oidc/OidcBaseTest.java | 9 +- .../http/oidc/QueryParamsBaseTest.java | 61 +++++++++++++ .../http/oidc/QueryParamsDisabledTest.java | 75 ++++++++++++++++ .../http/oidc/QueryParamsEnabledTest.java | 85 +++++++++++++++++++ 6 files changed, 250 insertions(+), 3 deletions(-) create mode 100644 http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsBaseTest.java create mode 100644 http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsDisabledTest.java create mode 100644 http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsEnabledTest.java diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java index 2052af1a0c..f42313b7f5 100644 --- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java +++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java @@ -65,6 +65,7 @@ public class Oidc { public static final String FACES_REQUEST = "Faces-Request"; public static final String GRANT_TYPE = "grant_type"; public static final String INVALID_TOKEN = "invalid_token"; + public static final String ISSUER = "iss"; public static final String LOGIN_HINT = "login_hint"; public static final String DOMAIN_HINT = "domain_hint"; public static final String MAX_AGE = "max_age"; @@ -113,6 +114,7 @@ public class Oidc { static final String KEYCLOAK_QUERY_BEARER_TOKEN = "k_query_bearer_token"; static final String DEFAULT_TOKEN_SIGNATURE_ALGORITHM = "RS256"; public static final String DISABLE_TYP_CLAIM_VALIDATION_PROPERTY_NAME = "wildfly.elytron.oidc.disable.typ.claim.validation"; + public static final String ALLOW_QUERY_PARAMS_PROPERTY_NAME = "wildfly.elytron.oidc.allow.query.params"; public static final String X_REQUESTED_WITH = "X-Requested-With"; public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java index 6b51d980d9..bdcc7168e8 100644 --- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java +++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java @@ -19,10 +19,12 @@ package org.wildfly.security.http.oidc; import static org.wildfly.security.http.oidc.ElytronMessages.log; +import static org.wildfly.security.http.oidc.Oidc.ALLOW_QUERY_PARAMS_PROPERTY_NAME; import static org.wildfly.security.http.oidc.Oidc.CLIENT_ID; import static org.wildfly.security.http.oidc.Oidc.CODE; import static org.wildfly.security.http.oidc.Oidc.DOMAIN_HINT; import static org.wildfly.security.http.oidc.Oidc.ERROR; +import static org.wildfly.security.http.oidc.Oidc.ISSUER; import static org.wildfly.security.http.oidc.Oidc.KC_IDP_HINT; import static org.wildfly.security.http.oidc.Oidc.LOGIN_HINT; import static org.wildfly.security.http.oidc.Oidc.MAX_AGE; @@ -43,6 +45,8 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -72,6 +76,17 @@ public class OidcRequestAuthenticator { protected String refreshToken; protected String strippedOauthParametersRequestUri; + static final boolean ALLOW_QUERY_PARAMS_PROPERTY; + + static { + ALLOW_QUERY_PARAMS_PROPERTY = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return Boolean.parseBoolean(System.getProperty(ALLOW_QUERY_PARAMS_PROPERTY_NAME, "false")); + } + }); + } + public OidcRequestAuthenticator(RequestAuthenticator requestAuthenticator, OidcHttpFacade facade, OidcClientConfiguration deployment, int sslRedirectPort, OidcTokenStore tokenStore) { this.reqAuthenticator = requestAuthenticator; this.facade = facade; @@ -369,11 +384,15 @@ protected AuthChallenge resolveCode(String code) { private static String stripOauthParametersFromRedirect(String uri) { uri = stripQueryParam(uri, CODE); uri = stripQueryParam(uri, STATE); - return stripQueryParam(uri, SESSION_STATE); + uri = stripQueryParam(uri, SESSION_STATE); + return stripQueryParam(uri, ISSUER); } private String rewrittenRedirectUri(String originalUri) { Map rewriteRules = deployment.getRedirectRewriteRules(); + if (ALLOW_QUERY_PARAMS_PROPERTY && (rewriteRules == null || rewriteRules.isEmpty())) { + return originalUri; + } try { URL url = new URL(originalUri); Map.Entry rule = null; diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java index 79ac806d56..da8efee998 100644 --- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java @@ -299,7 +299,12 @@ protected String getCookieString(HttpServerCookie cookie) { } protected void performAuthentication(InputStream oidcConfig, String username, String password, boolean loginToKeycloak, - int expectedDispatcherStatusCode, String expectedLocation, String clientPageText) throws Exception { + int expectedDispatcherStatusCode, String expectedLocation, String clientPageText) throws Exception { + performAuthentication(oidcConfig, username, password, loginToKeycloak, expectedDispatcherStatusCode, getClientUrl(), expectedLocation, clientPageText); + } + + protected void performAuthentication(InputStream oidcConfig, String username, String password, boolean loginToKeycloak, + int expectedDispatcherStatusCode, String clientUrl, String expectedLocation, String clientPageText) throws Exception { try { Map props = new HashMap<>(); OidcClientConfiguration oidcClientConfiguration = OidcClientConfigurationBuilder.build(oidcConfig); @@ -309,7 +314,7 @@ protected void performAuthentication(InputStream oidcConfig, String username, St oidcFactory = new OidcMechanismFactory(oidcClientContext); HttpServerAuthenticationMechanism mechanism = oidcFactory.createAuthenticationMechanism(OIDC_NAME, props, getCallbackHandler()); - URI requestUri = new URI(getClientUrl()); + URI requestUri = new URI(clientUrl); TestingHttpServerRequest request = new TestingHttpServerRequest(null, requestUri); mechanism.evaluateRequest(request); TestingHttpServerResponse response = request.getResponse(); diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsBaseTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsBaseTest.java new file mode 100644 index 0000000000..a5d7a52719 --- /dev/null +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsBaseTest.java @@ -0,0 +1,61 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.http.oidc; + +import static org.junit.Assume.assumeTrue; + +import org.junit.AfterClass; +import org.junit.BeforeClass; + +import io.restassured.RestAssured; +import okhttp3.mockwebserver.MockWebServer; + +/** + * Tests for the {@code wildfly.elytron.oidc.allow.query.params} system property. + * + * @author Farah Juma + */ +public class QueryParamsBaseTest extends OidcBaseTest { + + @BeforeClass + public static void startTestContainers() throws Exception { + assumeTrue("Docker isn't available, OIDC tests will be skipped", isDockerAvailable()); + KEYCLOAK_CONTAINER = new KeycloakContainer(); + KEYCLOAK_CONTAINER.start(); + sendRealmCreationRequest(KeycloakConfiguration.getRealmRepresentation(TEST_REALM, CLIENT_ID, CLIENT_SECRET, CLIENT_HOST_NAME, CLIENT_PORT, CLIENT_APP, 3, 3, true)); + client = new MockWebServer(); + client.start(CLIENT_PORT); + } + + @AfterClass + public static void generalCleanup() throws Exception { + if (KEYCLOAK_CONTAINER != null) { + RestAssured + .given() + .auth().oauth2(KeycloakConfiguration.getAdminAccessToken(KEYCLOAK_CONTAINER.getAuthServerUrl())) + .when() + .delete(KEYCLOAK_CONTAINER.getAuthServerUrl() + "/admin/realms/" + TEST_REALM).then().statusCode(204); + KEYCLOAK_CONTAINER.stop(); + } + if (client != null) { + client.shutdown(); + } + } + +} diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsDisabledTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsDisabledTest.java new file mode 100644 index 0000000000..e9d36b66bc --- /dev/null +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsDisabledTest.java @@ -0,0 +1,75 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.http.oidc; + +import static org.junit.Assume.assumeFalse; +import static org.wildfly.security.http.oidc.Oidc.ALLOW_QUERY_PARAMS_PROPERTY_NAME; + +import org.apache.http.HttpStatus; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Tests for disabling query params via the {@code wildfly.elytron.oidc.allow.query.params} system property. + * + * @author Farah Juma + */ +public class QueryParamsDisabledTest extends QueryParamsBaseTest { + + @BeforeClass + public static void beforeClass() { + assumeFalse("wildfly.elytron.oidc.allow.query.params should default to false", + Boolean.parseBoolean(System.getProperty(ALLOW_QUERY_PARAMS_PROPERTY_NAME))); + } + + /** + * Test successfully logging in without query params included in the URL. + */ + @Test + public void testSuccessfulAuthenticationWithoutQueryParamsWithSystemPropertyDisabled() throws Exception { + String originalUrl = getClientUrl(); + String expectedUrlAfterRedirect = originalUrl; + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, + KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, originalUrl, + expectedUrlAfterRedirect, CLIENT_PAGE_TEXT); + } + + /** + * Test successfully logging in with query params included in the URL. + * The query params should not be present upon redirect. + */ + @Test + public void testSuccessfulAuthenticationWithQueryParamsWithSystemPropertyDisabled() throws Exception { + String queryParams = "?myparam=abc"; + String originalUrl = getClientUrl() + queryParams; + String expectedUrlAfterRedirect = getClientUrl(); + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, + KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, + originalUrl, expectedUrlAfterRedirect, CLIENT_PAGE_TEXT); + + queryParams = "?one=abc&two=def&three=ghi"; + originalUrl = getClientUrl() + queryParams; + expectedUrlAfterRedirect = getClientUrl(); + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, + KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, originalUrl, + expectedUrlAfterRedirect, CLIENT_PAGE_TEXT); + } + +} + diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsEnabledTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsEnabledTest.java new file mode 100644 index 0000000000..ff320a28e0 --- /dev/null +++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/QueryParamsEnabledTest.java @@ -0,0 +1,85 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wildfly.security.http.oidc; + +import static org.wildfly.security.http.oidc.Oidc.ALLOW_QUERY_PARAMS_PROPERTY_NAME; + +import org.apache.http.HttpStatus; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Tests for enabling query params via the {@code wildfly.elytron.oidc.allow.query.params} system property. + * + * @author Farah Juma + */ +public class QueryParamsEnabledTest extends QueryParamsBaseTest { + + private static String ALLOW_QUERY_PARAMS_PROPERTY; + + @BeforeClass + public static void beforeClass() { + ALLOW_QUERY_PARAMS_PROPERTY = System.setProperty(ALLOW_QUERY_PARAMS_PROPERTY_NAME, "true"); + } + + @AfterClass + public static void afterClass() { + if (ALLOW_QUERY_PARAMS_PROPERTY == null) { + System.clearProperty(ALLOW_QUERY_PARAMS_PROPERTY_NAME); + } else { + System.setProperty(ALLOW_QUERY_PARAMS_PROPERTY_NAME, ALLOW_QUERY_PARAMS_PROPERTY); + } + } + + /** + * Test successfully logging in without query params included in the URL. + */ + @Test + public void testSuccessfulAuthenticationWithoutQueryParamsWithSystemPropertyEnabled() throws Exception { + String originalUrl = getClientUrl(); + String expectedUrlAfterRedirect = originalUrl; + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, + KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, originalUrl, + expectedUrlAfterRedirect, CLIENT_PAGE_TEXT); + } + + /** + * Test successfully logging in with query params included in the URL. + * The query params should be present upon redirect. + */ + @Test + public void testSuccessfulAuthenticationWithQueryParamsWithSystemPropertyEnabled() throws Exception { + String queryParams = "?myparam=abc"; + String originalUrl = getClientUrl() + queryParams; + String expectedUrlAfterRedirect = originalUrl; + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, + KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, originalUrl, + expectedUrlAfterRedirect, CLIENT_PAGE_TEXT); + + queryParams = "?one=abc&two=def&three=ghi"; + originalUrl = getClientUrl() + queryParams; + expectedUrlAfterRedirect = originalUrl; + performAuthentication(getOidcConfigurationInputStreamWithProviderUrl(), KeycloakConfiguration.ALICE, + KeycloakConfiguration.ALICE_PASSWORD, true, HttpStatus.SC_MOVED_TEMPORARILY, originalUrl, + expectedUrlAfterRedirect, CLIENT_PAGE_TEXT); + } + +} +