diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java index 052c04830f..97d1de97ee 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java @@ -55,7 +55,7 @@ public class RedirectUtils { public static Set resolveValidRedirects(UriInfo uriInfo, String rootUrl, Set validRedirects) { // If the valid redirect URI is relative (no scheme, host, port) then use the request's scheme, host, and port - Set resolveValidRedirects = new HashSet(); + Set resolveValidRedirects = new HashSet<>(); for (String validRedirect : validRedirects) { resolveValidRedirects.add(validRedirect); // add even relative urls. if (validRedirect.startsWith("/")) { @@ -70,7 +70,9 @@ public class RedirectUtils { private static Set getValidateRedirectUris(UriInfo uriInfo, RealmModel realm) { Set redirects = new HashSet<>(); for (ClientModel client : realm.getClients()) { - redirects.addAll(resolveValidRedirects(uriInfo, client.getRootUrl(), client.getRedirectUris())); + if (client.isEnabled()) { + redirects.addAll(resolveValidRedirects(uriInfo, client.getRootUrl(), client.getRedirectUris())); + } } return redirects; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java index 1f73f4f001..107493cb11 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java @@ -36,7 +36,6 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.util.TokenUtil; -import javax.ws.rs.core.Response; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -150,6 +149,13 @@ public class AssertEvents implements TestRule { .session(sessionId); } + public ExpectedEvent expectLogoutError(String error) { + return expect(EventType.LOGOUT_ERROR) + .error(error) + .client((String) null) + .user((String) null); + } + public ExpectedEvent expectRegister(String username, String email) { UserRepresentation user = username != null ? getUser(username) : null; return expect(EventType.REGISTER) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java index c47e6c841c..34b20c7a20 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java @@ -18,23 +18,40 @@ package org.keycloak.testsuite.client; import org.junit.Test; +import org.junit.Rule; import org.keycloak.OAuth2Constants; +import org.keycloak.OAuthErrorException; +import org.keycloak.common.util.KeycloakUriBuilder; +import org.keycloak.constants.ServiceUrlConstants; +import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; +import org.keycloak.testsuite.AssertEvents; +import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.RealmBuilder; +import java.net.URI; import javax.ws.rs.client.Client; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.keycloak.testsuite.util.Matchers.statusCodeIs; /** * @author Thomas Darimont */ public class ClientRedirectTest extends AbstractTestRealmKeycloakTest { + @Rule + public AssertEvents events = new AssertEvents(this); + @Override public void configureTestRealm(RealmRepresentation testRealm) { RealmBuilder.edit(testRealm) @@ -73,4 +90,37 @@ public class ClientRedirectTest extends AbstractTestRealmKeycloakTest { assertEquals(303, response.getStatus()); client.close(); } + + // KEYCLOAK-7707 + @Test + public void testRedirectToDisabledClientRedirectURI() throws Exception { + log.debug("Creating disabled-client with redirect uri \"*\""); + String clientId; + try (Response create = adminClient.realm("test").clients().create(ClientBuilder.create().clientId("disabled-client").enabled(false).redirectUris("*").build())) { + clientId = ApiUtil.getCreatedId(create); + assertThat(create, statusCodeIs(Status.CREATED)); + } + + try { + log.debug("log in"); + oauth.doLogin("test-user@localhost", "password"); + events.expectLogin().assertEvent(); + + URI logout = KeycloakUriBuilder.fromUri(suiteContext.getAuthServerInfo().getBrowserContextRoot().toURI()) + .path("auth" + ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH) + .queryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM, "http://example.org/redirected") + .build("test"); + + log.debug("log out using: " + logout.toURL()); + driver.navigate().to(logout.toURL()); + log.debug("Current URL: " + driver.getCurrentUrl()); + + log.debug("check logout_error"); + events.expectLogoutError(OAuthErrorException.INVALID_REDIRECT_URI).assertEvent(); + assertThat(driver.getCurrentUrl(), is(not(equalTo("http://example.org/redirected")))); + } finally { + log.debug("removing disabled-client"); + adminClient.realm("test").clients().get(clientId).remove(); + } + } }