From 767d1fcc206ae0b0c5d365d999eebaadc342746e Mon Sep 17 00:00:00 2001 From: mposolda Date: Fri, 24 Apr 2015 18:41:00 +0200 Subject: [PATCH 1/2] Don't use JPA eventsStore in mongo tests --- testsuite/integration/pom.xml | 4 ++-- .../src/test/resources/META-INF/keycloak-server.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml index d763ca1155..527d91f389 100755 --- a/testsuite/integration/pom.xml +++ b/testsuite/integration/pom.xml @@ -379,7 +379,7 @@ jpa jpa - jpa + jpa jpa @@ -443,7 +443,7 @@ mongo mongo - mongo + mongo mongo ${keycloak.connectionsMongo.host} ${keycloak.connectionsMongo.port} diff --git a/testsuite/integration/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration/src/test/resources/META-INF/keycloak-server.json index 2c56c58f53..e2ebf541b3 100755 --- a/testsuite/integration/src/test/resources/META-INF/keycloak-server.json +++ b/testsuite/integration/src/test/resources/META-INF/keycloak-server.json @@ -4,7 +4,7 @@ }, "eventsStore": { - "provider": "${keycloak.eventStore.provider:jpa}" + "provider": "${keycloak.eventsStore.provider:jpa}" }, "eventsListener": { From a338626d2baf6859c4bc3712a3a1f2b3d5a8dd79 Mon Sep 17 00:00:00 2001 From: mposolda Date: Fri, 24 Apr 2015 18:42:03 +0200 Subject: [PATCH 2/2] KEYCLOAK-1216 Click on 'Logout all sessions' in Account mgmt should propagate logout to the apps --- .../protocol/oidc/OIDCLoginProtocol.java | 3 ++- .../managers/AuthenticationManager.java | 26 +++++++++++-------- .../services/resources/AccountService.java | 6 ++++- .../testsuite/adapter/AdapterTest.java | 8 ++++++ .../adapter/AdapterTestStrategy.java | 20 ++++++++++++++ .../testsuite/pages/AccountSessionsPage.java | 14 ++++++++-- .../org/keycloak/testsuite/Jetty8Test.java | 8 ++++++ .../org/keycloak/testsuite/Jetty9Test.java | 8 ++++++ .../org/keycloak/testsuite/Jetty9Test.java | 8 ++++++ .../org/keycloak/testsuite/TomcatTest.java | 8 ++++++ .../org/keycloak/testsuite/Tomcat7Test.java | 8 ++++++ .../org/keycloak/testsuite/TomcatTest.java | 8 ++++++ 12 files changed, 110 insertions(+), 15 deletions(-) diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java index 88525dbd71..06eefe0f53 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java @@ -165,7 +165,8 @@ public class OIDCLoginProtocol implements LoginProtocol { @Override public void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) { if (!(clientSession.getClient() instanceof ClientModel)) return; - ClientModel app = (ClientModel)clientSession.getClient(); + ClientModel app = clientSession.getClient(); + // TODO: Probably non-effective to build executor every time from scratch. Should be likely shared for whole OIDCLoginProtocolFactory ApacheHttpClient4Executor executor = ResourceAdminManager.createExecutor(); try { diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java index 8e363bb95f..6a96037c6f 100755 --- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java @@ -113,22 +113,26 @@ public class AuthenticationManager { expireUserSessionCookie(session, userSession, realm, uriInfo, headers, connection); for (ClientSessionModel clientSession : userSession.getClientSessions()) { - ClientModel client = clientSession.getClient(); - if (client instanceof ClientModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) { - String authMethod = clientSession.getAuthMethod(); - if (authMethod == null) continue; // must be a keycloak service like account - LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod); - protocol.setRealm(realm) - .setHttpHeaders(headers) - .setUriInfo(uriInfo); - protocol.backchannelLogout(userSession, clientSession); - clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT); - } + backchannelLogoutClientSession(session, realm, clientSession, userSession, uriInfo, headers); } userSession.setState(UserSessionModel.State.LOGGED_OUT); session.sessions().removeUserSession(realm, userSession); } + public static void backchannelLogoutClientSession(KeycloakSession session, RealmModel realm, ClientSessionModel clientSession, UserSessionModel userSession, UriInfo uriInfo, HttpHeaders headers) { + ClientModel client = clientSession.getClient(); + if (client instanceof ClientModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) { + String authMethod = clientSession.getAuthMethod(); + if (authMethod == null) return; // must be a keycloak service like account + LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod); + protocol.setRealm(realm) + .setHttpHeaders(headers) + .setUriInfo(uriInfo); + protocol.backchannelLogout(userSession, clientSession); + clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT); + } + } + public static Response browserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) { if (userSession == null) return null; diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java index 9b1edaedf6..b9e8d89c93 100755 --- a/services/src/main/java/org/keycloak/services/resources/AccountService.java +++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java @@ -478,7 +478,10 @@ public class AccountService { csrfCheck(stateChecker); UserModel user = auth.getUser(); - session.sessions().removeUserSessions(realm, user); + List userSessions = session.sessions().getUserSessions(realm, user); + for (UserSessionModel userSession : userSessions) { + AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers); + } UriBuilder builder = Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "sessionsPage"); String referrer = uriInfo.getQueryParameters().getFirst("referrer"); @@ -519,6 +522,7 @@ public class AccountService { List clientSessions = userSession.getClientSessions(); for (ClientSessionModel clientSession : clientSessions) { if (clientSession.getClient().getId().equals(clientId)) { + AuthenticationManager.backchannelLogoutClientSession(session, realm, clientSession, userSession, uriInfo, headers); TokenManager.dettachClientSession(session.sessions(), realm, clientSession); } } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java index 15dfca3074..2ea5ecceaa 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java @@ -155,4 +155,12 @@ public class AdapterTest { testStrategy.testAdminApplicationLogout(); } + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } + } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java index f9f82dcaf4..5c21db1a4a 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java @@ -44,6 +44,7 @@ import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceAdminManager; import org.keycloak.services.resources.admin.AdminRoot; import org.keycloak.testsuite.OAuthClient; +import org.keycloak.testsuite.pages.AccountSessionsPage; import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.KeycloakRule; @@ -94,6 +95,9 @@ public class AdapterTestStrategy extends ExternalResource { @WebResource protected InputPage inputPage; + @WebResource + protected AccountSessionsPage accountSessionsPage; + protected String LOGIN_URL = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(AUTH_SERVER_URL)).build("demo").toString(); public AdapterTestStrategy(String AUTH_SERVER_URL, String APP_SERVER_BASE_URL, AbstractKeycloakRule keycloakRule) { @@ -592,6 +596,22 @@ public class AdapterTestStrategy extends ExternalResource { Assert.assertTrue(pageSource.contains("Counter=3")); } + /** + * KEYCLOAK-1216 + */ + public void testAccountManagementSessionsLogout() throws Throwable { + // login as bburke + loginAndCheckSession(driver, loginPage); + + // logout sessions in account management + accountSessionsPage.realm("demo"); + accountSessionsPage.open(); + accountSessionsPage.logoutAll(); + + // Assert I need to login again (logout was propagated to the app) + loginAndCheckSession(driver, loginPage); + } + protected void loginAndCheckSession(WebDriver driver, LoginPage loginPage) { driver.navigate().to(APP_SERVER_BASE_URL + "/session-portal"); String currentUrl = driver.getCurrentUrl(); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java index bfadc6d339..1b52a566c1 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java @@ -36,7 +36,9 @@ import java.util.List; */ public class AccountSessionsPage extends AbstractAccountPage { - private static String PATH = Urls.accountSessionsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), "test").toString(); + private String realmName = "test"; + + private String path = Urls.accountSessionsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), "test").toString(); @FindBy(id = "logout-all-sessions") private WebElement logoutAllLink; @@ -45,8 +47,16 @@ public class AccountSessionsPage extends AbstractAccountPage { return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().endsWith("/account/sessions"); } + public void realm(String realmName) { + this.realmName = realmName; + } + + public String getPath() { + return Urls.accountSessionsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), realmName).toString(); + } + public void open() { - driver.navigate().to(PATH); + driver.navigate().to(getPath()); } public void logoutAll() { diff --git a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java index 7c40fc2e07..6232ae5945 100755 --- a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java +++ b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java @@ -172,4 +172,12 @@ public class Jetty8Test { public void testAdminApplicationLogout() throws Throwable { testStrategy.testAdminApplicationLogout(); } + + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } } diff --git a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java index 4b87597b98..09bffc7366 100755 --- a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java +++ b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java @@ -172,4 +172,12 @@ public class Jetty9Test { public void testAdminApplicationLogout() throws Throwable { testStrategy.testAdminApplicationLogout(); } + + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } } diff --git a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java index ceab804ac0..26db13a271 100755 --- a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java +++ b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java @@ -172,4 +172,12 @@ public class Jetty9Test { public void testAdminApplicationLogout() throws Throwable { testStrategy.testAdminApplicationLogout(); } + + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } } diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java index 9809e09417..5393b65210 100755 --- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java +++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java @@ -161,6 +161,14 @@ public class TomcatTest { testStrategy.testAdminApplicationLogout(); } + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } + static String getBaseDirectory() { String dirPath = null; String relativeDirPath = "testsuite" + File.separator + "tomcat6" + File.separator + "target"; diff --git a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java index ef06a176f7..7a38655c1d 100755 --- a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java +++ b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java @@ -165,6 +165,14 @@ public class Tomcat7Test { testStrategy.testAdminApplicationLogout(); } + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } + private static String getBaseDirectory() { String dirPath = null; diff --git a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java index 86fcac0d07..8c1372a214 100755 --- a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java +++ b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java @@ -166,6 +166,14 @@ public class TomcatTest { testStrategy.testAdminApplicationLogout(); } + /** + * KEYCLOAK-1216 + */ + @Test + public void testAccountManagementSessionsLogout() throws Throwable { + testStrategy.testAccountManagementSessionsLogout(); + } + private static String getBaseDirectory() { String dirPath = null; String relativeDirPath = "testsuite" + File.separator + "tomcat8" + File.separator + "target";