From 03bfca5e4155645f454737c48d2ee781c72f7999 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Tue, 31 Mar 2015 19:33:43 -0400 Subject: [PATCH] expire cookie on backchannel --- .../keycloak/protocol/saml/SamlProtocol.java | 1 + .../managers/AuthenticationManager.java | 25 +++++++++++++++---- .../testsuite/account/AccountTest.java | 2 +- .../adapter/AdapterTestStrategy.java | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java index d71b95b61f..dc2caa8509 100755 --- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java +++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java @@ -431,6 +431,7 @@ public class SamlProtocol implements LoginProtocol { logoutServiceUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE); } if (logoutServiceUrl == null && client instanceof ApplicationModel) logoutServiceUrl = ((ApplicationModel)client).getManagementUrl(); + if (logoutServiceUrl == null || logoutServiceUrl.trim().equals("")) return null; return ResourceAdminManager.resolveUri(uriInfo.getRequestUri(), logoutServiceUrl); } 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 5fc15bf7c1..8ebcf74eb7 100755 --- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java @@ -85,14 +85,29 @@ public class AuthenticationManager { return userSession != null && userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime; } + public static void expireUserSessionCookie(KeycloakSession session, UserSessionModel userSession, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, ClientConnection connection) { + try { + // check to see if any identity cookie is set with the same session and expire it if necessary + Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE); + if (cookie == null) return; + String tokenString = cookie.getValue(); + AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), false); + UserSessionModel cookieSession = session.sessions().getUserSession(realm, token.getSessionState()); + if (cookieSession == null || !cookieSession.getId().equals(userSession.getId())) return; + expireIdentityCookie(realm, uriInfo, connection); + expireRememberMeCookie(realm, uriInfo, connection); + } catch (Exception e) { + } + + } + public static void backchannelLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) { if (userSession == null) return; UserModel user = userSession.getUser(); userSession.setState(UserSessionModel.State.LOGGING_OUT); logger.debugv("Logging out: {0} ({1})", user.getUsername(), userSession.getId()); - //expireIdentityCookie(realm, uriInfo, connection); - //expireRememberMeCookie(realm, uriInfo, connection); + expireUserSessionCookie(session, userSession, realm, uriInfo, headers, connection); for (ClientSessionModel clientSession : userSession.getClientSessions()) { ClientModel client = clientSession.getClient(); @@ -293,7 +308,7 @@ public class AuthenticationManager { return authenticateIdentityCookie(session, realm, uriInfo, connection, headers, true); } - public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, boolean checkActive) { + public static AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, boolean checkActive) { Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE); if (cookie == null || "".equals(cookie.getValue())) { logger.debugv("Could not find cookie: {0}", KEYCLOAK_IDENTITY_COOKIE); @@ -443,7 +458,7 @@ public class AuthenticationManager { } } - protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) { + protected static AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) { try { AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), checkActive); if (checkActive) { @@ -594,7 +609,7 @@ public class AuthenticationManager { SUCCESS, ACCOUNT_TEMPORARILY_DISABLED, ACCOUNT_DISABLED, ACTIONS_REQUIRED, INVALID_USER, INVALID_CREDENTIALS, MISSING_PASSWORD, MISSING_TOTP, FAILED } - public class AuthResult { + public static class AuthResult { private final UserModel user; private final UserSessionModel session; private final AccessToken token; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java index ce61d3351c..8482ce0e4f 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java @@ -157,7 +157,7 @@ public class AccountTest { }); } - //@Test @Ignore + @Test @Ignore public void runit() throws Exception { Thread.sleep(10000000); } 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 6d3c32b804..8feaac569e 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 @@ -223,7 +223,7 @@ public class AdapterTestStrategy extends ExternalResource { }); Integer custSessionsCount = stats.get("customer-portal"); Assert.assertNotNull(custSessionsCount); - Assert.assertTrue(1 == custSessionsCount); + Assert.assertEquals(1, custSessionsCount.intValue()); Integer prodStatsCount = stats.get("product-portal"); Assert.assertNotNull(prodStatsCount); Assert.assertTrue(1 == prodStatsCount);