Details
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 052c048..97d1de9 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<String> resolveValidRedirects(UriInfo uriInfo, String rootUrl, Set<String> validRedirects) {
// If the valid redirect URI is relative (no scheme, host, port) then use the request's scheme, host, and port
- Set<String> resolveValidRedirects = new HashSet<String>();
+ Set<String> 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<String> getValidateRedirectUris(UriInfo uriInfo, RealmModel realm) {
Set<String> 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 1f73f4f..107493c 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 c47e6c8..34b20c7 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 <a href="mailto:thomas.darimont@gmail.com">Thomas Darimont</a>
*/
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();
+ }
+ }
}