KEYCLOAK-16517 Make sure that just real clients with standardFlow or implicitFlow enabled are considered for redirectUri during logout

This commit is contained in:
mposolda 2021-02-10 16:50:55 +01:00 committed by Marek Posolda
parent 0058011265
commit ed8d5a257f
2 changed files with 44 additions and 1 deletions

View file

@ -24,6 +24,7 @@ import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakUriInfo;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.services.Urls;
import org.keycloak.services.util.ResolveRelative;
@ -72,7 +73,7 @@ public class RedirectUtils {
private static Set<String> getValidateRedirectUris(KeycloakSession session) {
return session.getContext().getRealm().getClientsStream()
.filter(ClientModel::isEnabled)
.filter(client -> client.isEnabled() && OIDCLoginProtocol.LOGIN_PROTOCOL.equals(client.getProtocol()) && !client.isBearerOnly() && (client.isStandardFlowEnabled() || client.isImplicitFlowEnabled()))
.map(c -> resolveValidRedirects(session, c.getRootUrl(), c.getRedirectUris()))
.flatMap(Collection::stream)
.collect(Collectors.toSet());

View file

@ -21,9 +21,12 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.common.Profile;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.models.Constants;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.Assert;
@ -38,12 +41,14 @@ import org.keycloak.testsuite.pages.LoginPage;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
import org.keycloak.testsuite.auth.page.account.AccountManagement;
@ -51,6 +56,7 @@ import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
import org.keycloak.testsuite.util.ClientManager;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.ServerURLs;
import org.keycloak.testsuite.util.WaitUtils;
/**
@ -111,6 +117,42 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
events.expectLogout(sessionId2).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
}
// KEYCLOAK-16517 Make sure that just real clients with standardFlow or implicitFlow enabled are considered for redirectUri
@Test
public void logoutRedirectWithStarRedirectUriForDirectGrantClient() {
// Set "*" as redirectUri for some directGrant client
ClientResource clientRes = ApiUtil.findClientByClientId(testRealm(), "direct-grant");
ClientRepresentation clientRepOrig = clientRes.toRepresentation();
ClientRepresentation clientRep = clientRes.toRepresentation();
clientRep.setStandardFlowEnabled(false);
clientRep.setImplicitFlowEnabled(false);
clientRep.setRedirectUris(Collections.singletonList("*"));
clientRes.update(clientRep);
try {
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
events.expectLogin().assertEvent();
String invalidRedirectUri = ServerURLs.getAuthServerContextRoot() + "/bar";
String logoutUrl = oauth.getLogoutUrl().redirectUri(invalidRedirectUri).build();
driver.navigate().to(logoutUrl);
events.expectLogoutError(Errors.INVALID_REDIRECT_URI).assertEvent();
assertCurrentUrlDoesntStartWith(invalidRedirectUri);
errorPage.assertCurrent();
Assert.assertEquals("Invalid redirect uri", errorPage.getError());
} finally {
// Revert
clientRes.update(clientRepOrig);
}
}
@Test
public void logoutSession() {
loginPage.open();