Skip to content

Commit

Permalink
KEYCLOAK-942 Incorrect condition in ResourceAdminManager could cause …
Browse files Browse the repository at this point in the history
…global logout
  • Loading branch information
mposolda committed Jan 8, 2015
1 parent e62858c commit fff8ae9
Show file tree
Hide file tree
Showing 16 changed files with 217 additions and 52 deletions.
Expand Up @@ -184,7 +184,12 @@ protected boolean logoutClientSessions(URI requestUri, RealmModel realm, Applica
}
}

if (managementUrl.contains(APPLICATION_SESSION_HOST_PROPERTY) && adapterSessionIds != null) {
if (adapterSessionIds == null || adapterSessionIds.isEmpty()) {
logger.debugv("Can't logout {0}: no logged adapter sessions", resource.getName());
return false;
}

if (managementUrl.contains(APPLICATION_SESSION_HOST_PROPERTY)) {
boolean allPassed = true;
// Send logout separately to each host (needed for single-sign-out in cluster for non-distributable apps - KEYCLOAK-748)
for (Map.Entry<String, List<String>> entry : adapterSessionIds.entrySet()) {
Expand All @@ -197,13 +202,11 @@ protected boolean logoutClientSessions(URI requestUri, RealmModel realm, Applica
return allPassed;
} else {
// Send single logout request
List<String> allSessionIds = null;
if (adapterSessionIds != null) {
allSessionIds = new ArrayList<String>();
for (List<String> currentIds : adapterSessionIds.values()) {
allSessionIds.addAll(currentIds);
}
List<String> allSessionIds = new ArrayList<String>();
for (List<String> currentIds : adapterSessionIds.values()) {
allSessionIds.addAll(currentIds);
}

return sendLogoutRequest(realm, resource, allSessionIds, client, 0, managementUrl);
}
} else {
Expand Down
Expand Up @@ -79,9 +79,7 @@ public class AdapterTest {
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
RealmModel realm = manager.importRealm(representation);

RealmModel realm = AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
realmPublicKey = realm.getPublicKey();

URL url = getClass().getResource("/adapter-test/cust-app-keycloak.json");
Expand Down Expand Up @@ -184,4 +182,12 @@ public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {

}

/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}

}
Expand Up @@ -28,6 +28,7 @@
import org.keycloak.Config;
import org.keycloak.OAuth2Constants;
import org.keycloak.Version;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
Expand All @@ -38,15 +39,20 @@
import org.keycloak.protocol.oidc.OpenIDConnectService;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.resources.admin.AdminRoot;
import org.keycloak.services.resources.admin.ApplicationsResource;
import org.keycloak.services.resources.admin.RealmAdminResource;
import org.keycloak.services.resources.admin.RealmsAdminResource;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testutils.KeycloakServer;
import org.keycloak.util.BasicAuthHelper;
import org.openqa.selenium.WebDriver;

Expand Down Expand Up @@ -106,6 +112,15 @@ public AdapterTestStrategy(String AUTH_SERVER_URL, String APP_SERVER_BASE_URL, A
if (addSlash) slash = "/";
}

public static RealmModel baseAdapterTestInitialization(KeycloakSession session, RealmManager manager, RealmModel adminRealm, Class<?> clazz) {
// Required by admin client
adminRealm.setPasswordCredentialGrantAllowed(true);

RealmRepresentation representation = KeycloakServer.loadJson(clazz.getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
RealmModel demoRealm = manager.importRealm(representation);
return demoRealm;
}

@Override
protected void before() throws Throwable {
super.before();
Expand Down Expand Up @@ -562,6 +577,25 @@ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmMod
}, "demo");
}

/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
// login as bburke
loginAndCheckSession(driver, loginPage);

// logout mposolda with admin client
Keycloak keycloakAdmin = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CONSOLE_APPLICATION);
keycloakAdmin.realm("demo").applications().get("session-portal").logoutUser("mposolda");

// bburke should be still logged with original httpSession in our browser window
driver.navigate().to(APP_SERVER_BASE_URL + "/session-portal");
Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/session-portal" + slash);
String pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("Counter=3"));
}

protected void loginAndCheckSession(WebDriver driver, LoginPage loginPage) {
driver.navigate().to(APP_SERVER_BASE_URL + "/session-portal");
String currentUrl = driver.getCurrentUrl();
Expand Down
Expand Up @@ -28,6 +28,21 @@
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
}
],
"roles" : {
Expand Down
Expand Up @@ -21,62 +21,35 @@
*/
package org.keycloak.testsuite;

import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.jetty.AbstractKeycloakJettyAuthenticator;
import org.keycloak.adapters.jetty.KeycloakJettyAuthenticator;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OpenIDConnectService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testutils.KeycloakServer;
import org.openqa.selenium.WebDriver;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.UriBuilder;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;

/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class Jetty9Test {
public class Jetty8Test {
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
RealmModel realm = manager.importRealm(representation);
AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
}
};

Expand All @@ -89,7 +62,7 @@ public static void initJetty() throws Exception {
List<Handler> list = new ArrayList<Handler>();
System.setProperty("app.server.base.url", "http://localhost:8082");
System.setProperty("my.host.name", "localhost");
URL dir = Jetty9Test.class.getResource("/adapter-test/demorealm.json");
URL dir = Jetty8Test.class.getResource("/adapter-test/demorealm.json");
File base = new File(dir.getFile()).getParentFile();
list.add(new WebAppContext(new File(base, "customer-portal").toString(), "/customer-portal"));
list.add(new WebAppContext(new File(base, "customer-db").toString(), "/customer-db"));
Expand Down Expand Up @@ -190,4 +163,13 @@ public void testSingleSessionInvalidated() throws Throwable {
public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {
testStrategy.testSessionInvalidatedAfterFailedRefresh();

}}
}

/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}
}
Expand Up @@ -28,6 +28,21 @@
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
}
],
"roles" : {
Expand Down
Expand Up @@ -75,8 +75,7 @@ public class Jetty9Test {
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
RealmModel realm = manager.importRealm(representation);
AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
}
};

Expand Down Expand Up @@ -191,4 +190,12 @@ public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {
testStrategy.testSessionInvalidatedAfterFailedRefresh();

}

/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}
}
Expand Up @@ -28,6 +28,21 @@
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
}
],
"roles" : {
Expand Down
Expand Up @@ -75,8 +75,7 @@ public class Jetty9Test {
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
RealmModel realm = manager.importRealm(representation);
AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
}
};

Expand Down Expand Up @@ -191,4 +190,12 @@ public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {
testStrategy.testSessionInvalidatedAfterFailedRefresh();

}

/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}
}
Expand Up @@ -28,6 +28,21 @@
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
}
],
"roles" : {
Expand Down
Expand Up @@ -63,8 +63,7 @@ public class TomcatTest {
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
RealmModel realm = manager.importRealm(representation);
AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
}
};

Expand Down Expand Up @@ -173,6 +172,14 @@ public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {

}

/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}

static String getBaseDirectory() {
String dirPath = null;
String relativeDirPath = "testsuite" + File.separator + "tomcat6" + File.separator + "target";
Expand Down
15 changes: 15 additions & 0 deletions testsuite/tomcat6/src/test/resources/adapter-test/demorealm.json
Expand Up @@ -28,6 +28,21 @@
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
}
],
"roles" : {
Expand Down

0 comments on commit fff8ae9

Please sign in to comment.