diff --git a/services/src/main/java/org/keycloak/services/util/ServerCookie.java b/core/src/main/java/org/keycloak/util/ServerCookie.java similarity index 99% rename from services/src/main/java/org/keycloak/services/util/ServerCookie.java rename to core/src/main/java/org/keycloak/util/ServerCookie.java index d41cc2e05b..a15c739f2c 100755 --- a/services/src/main/java/org/keycloak/services/util/ServerCookie.java +++ b/core/src/main/java/org/keycloak/util/ServerCookie.java @@ -1,4 +1,4 @@ -package org.keycloak.services.util; +package org.keycloak.util; import java.io.Serializable; import java.text.DateFormat; diff --git a/distribution/appliance-dist/assembly.xml b/distribution/appliance-dist/assembly.xml index 9bef5b2a67..942162d321 100755 --- a/distribution/appliance-dist/assembly.xml +++ b/distribution/appliance-dist/assembly.xml @@ -80,6 +80,7 @@ org.keycloak:keycloak-wildfly-adapter-dist:zip org.keycloak:keycloak-as7-adapter-dist:zip org.keycloak:keycloak-eap6-adapter-dist:zip + org.keycloak:keycloak-tomcat6-adapter-dist:zip org.keycloak:keycloak-tomcat7-adapter-dist:zip org.keycloak:keycloak-tomcat8-adapter-dist:zip org.keycloak:keycloak-jetty81-adapter-dist:zip diff --git a/distribution/appliance-dist/pom.xml b/distribution/appliance-dist/pom.xml index 88f9fd5475..d2b462680e 100755 --- a/distribution/appliance-dist/pom.xml +++ b/distribution/appliance-dist/pom.xml @@ -26,6 +26,12 @@ ${project.version} zip + + org.keycloak + keycloak-tomcat6-adapter-dist + ${project.version} + zip + org.keycloak keycloak-tomcat7-adapter-dist diff --git a/distribution/pom.xml b/distribution/pom.xml index baf7a0346c..de6a724d2c 100755 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -27,6 +27,7 @@ modules as7-adapter-zip + tomcat6-adapter-zip tomcat7-adapter-zip tomcat8-adapter-zip eap6-adapter-zip diff --git a/distribution/tomcat6-adapter-zip/assembly.xml b/distribution/tomcat6-adapter-zip/assembly.xml new file mode 100755 index 0000000000..6ddc252be4 --- /dev/null +++ b/distribution/tomcat6-adapter-zip/assembly.xml @@ -0,0 +1,23 @@ + + war-dist + + + zip + + false + + + + false + true + true + + org.keycloak:keycloak-tomcat6-adapter + + + org.apache.tomcat:catalina + + + + + diff --git a/distribution/tomcat6-adapter-zip/pom.xml b/distribution/tomcat6-adapter-zip/pom.xml new file mode 100755 index 0000000000..0ea2f652df --- /dev/null +++ b/distribution/tomcat6-adapter-zip/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + + keycloak-parent + org.keycloak + 1.1.0.Beta2-SNAPSHOT + ../../pom.xml + + + keycloak-tomcat6-adapter-dist + pom + Keycloak Tomcat 6 Adapter Distro + + + + + org.keycloak + keycloak-tomcat6-adapter + ${project.version} + + + + + + maven-assembly-plugin + 2.4 + + + assemble + package + + single + + + + assembly.xml + + + target + + + target/assembly/work + + false + + + + + + + + diff --git a/distribution/war-dist/assembly.xml b/distribution/war-dist/assembly.xml index 93e08a34fa..40fdfd8652 100755 --- a/distribution/war-dist/assembly.xml +++ b/distribution/war-dist/assembly.xml @@ -31,6 +31,7 @@ org.keycloak:keycloak-wildfly-adapter-dist:zip org.keycloak:keycloak-as7-adapter-dist:zip org.keycloak:keycloak-eap6-adapter-dist:zip + org.keycloak:keycloak-tomcat6-adapter-dist:zip org.keycloak:keycloak-tomcat7-adapter-dist:zip org.keycloak:keycloak-tomcat8-adapter-dist:zip org.keycloak:keycloak-jetty81-adapter-dist:zip diff --git a/distribution/war-dist/pom.xml b/distribution/war-dist/pom.xml index dbef9dad42..07b5c99880 100755 --- a/distribution/war-dist/pom.xml +++ b/distribution/war-dist/pom.xml @@ -26,6 +26,12 @@ ${project.version} zip + + org.keycloak + keycloak-tomcat6-adapter-dist + ${project.version} + zip + org.keycloak keycloak-tomcat7-adapter-dist diff --git a/docbook/reference/en/en-US/modules/tomcat-adapter.xml b/docbook/reference/en/en-US/modules/tomcat-adapter.xml index 7bff1f5c61..0f3d75e2e4 100755 --- a/docbook/reference/en/en-US/modules/tomcat-adapter.xml +++ b/docbook/reference/en/en-US/modules/tomcat-adapter.xml @@ -1,14 +1,14 @@
- Tomcat 7 and 8 Adapter + Tomcat 6, 7 and 8 Adapters - To be able to secure WAR apps deployed on Tomcat 7 and 8 you must install the Keycloak Tomcat 7 or 8 adapter + To be able to secure WAR apps deployed on Tomcat 6, 7 and 8 you must install the Keycloak Tomcat 6, 7 or 8 adapter into your Tomcat installation. You then have to provide some extra configuration in each WAR you deploy to Tomcat. Let's go over these steps.
Adapter Installation - There is a adapter zip file for Tomcat 7/8 in the adapters/ directory in the Keycloak appliance + There is a adapter zip file for Tomcat in the adapters/ directory in the Keycloak appliance or war distribution. You must unzip this file into Tomcat's lib/ directory. Including adapter's jars within your WEB-INF/lib directory will not work! The Keycloak adapter is implemented as a Valve and valve code must reside in Tomcat's main lib/ directory. @@ -16,6 +16,8 @@ $ cd $TOMCAT_HOME/lib +$ unzip keycloak-tomcat6-adapter-dist.zip + or $ unzip keycloak-tomcat7-adapter-dist.zip or $ unzip keycloak-tomcat8-adapter-dist.zip diff --git a/integration/tomcat/pom.xml b/integration/tomcat/pom.xml index 146a9bb67e..a279b1d45d 100755 --- a/integration/tomcat/pom.xml +++ b/integration/tomcat/pom.xml @@ -15,6 +15,7 @@ tomcat-core + tomcat6 tomcat7 tomcat8 diff --git a/integration/tomcat/tomcat-core/pom.xml b/integration/tomcat/tomcat-core/pom.xml index 0e1277420f..ca0a64debe 100755 --- a/integration/tomcat/tomcat-core/pom.xml +++ b/integration/tomcat/tomcat-core/pom.xml @@ -13,7 +13,8 @@ Keycloak Tomcat Core Integration - 7.0.52 + + 6.0.41 @@ -58,15 +59,17 @@ org.codehaus.jackson jackson-xc + org.apache.tomcat - tomcat-catalina + catalina ${tomcat.version} compile diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java index 7d207ac2ce..cb05e72c13 100755 --- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java +++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java @@ -3,13 +3,11 @@ package org.keycloak.adapters.tomcat; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; -import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; import org.apache.catalina.Manager; import org.apache.catalina.authenticator.FormAuthenticator; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; -import org.apache.catalina.core.StandardContext; import org.keycloak.KeycloakSecurityContext; import org.keycloak.constants.AdapterConstants; import org.keycloak.adapters.AdapterDeploymentContext; @@ -55,13 +53,9 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat @Override public void lifecycleEvent(LifecycleEvent event) { if (Lifecycle.START_EVENT.equals(event.getType())) { - try { - startDeployment(); - } catch (LifecycleException e) { - log.severe("Error starting deployment. " + e.getMessage()); - } + cache = false; } else if (Lifecycle.AFTER_START_EVENT.equals(event.getType())) { - initInternal(); + keycloakInit(); } else if (event.getType() == Lifecycle.BEFORE_STOP_EVENT) { beforeStop(); } @@ -80,19 +74,11 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat tokenStore.logout(); request.removeAttribute(KeycloakSecurityContext.class.getName()); } - } - - - public void startDeployment() throws LifecycleException { - super.start(); - StandardContext standardContext = (StandardContext) context; - standardContext.addLifecycleListener(this); - cache = false; + request.setUserPrincipal(null); } @SuppressWarnings("UseSpecificCatch") - @Override - public void initInternal() { + public void keycloakInit() { // Possible scenarios: // 1) The deployment has a keycloak.config.resolver specified and it exists: // Outcome: adapter uses the resolver @@ -182,6 +168,8 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat } } + protected abstract GenericPrincipalFactory createPrincipalFactory(); + protected boolean authenticateInternal(Request request, HttpServletResponse response) { CatalinaHttpFacade facade = new CatalinaHttpFacade(request, response); KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade); @@ -192,7 +180,7 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat nodesRegistrationManagement.tryRegister(deployment); - CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, this, tokenStore, facade, request); + CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, this, tokenStore, facade, request, createPrincipalFactory()); AuthOutcome outcome = authenticator.authenticate(); if (outcome == AuthOutcome.AUTHENTICATED) { if (facade.isEnded()) { @@ -237,9 +225,9 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat } if (resolvedDeployment.getTokenStore() == TokenStore.SESSION) { - store = new CatalinaSessionTokenStore(request, resolvedDeployment, userSessionManagement); + store = new CatalinaSessionTokenStore(request, resolvedDeployment, userSessionManagement, createPrincipalFactory()); } else { - store = new CatalinaCookieTokenStore(request, facade, resolvedDeployment); + store = new CatalinaCookieTokenStore(request, facade, resolvedDeployment, createPrincipalFactory()); } request.setNote(TOKEN_STORE_NOTE, store); diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaCookieTokenStore.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaCookieTokenStore.java index a0cf006f45..229efa3fe9 100755 --- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaCookieTokenStore.java +++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaCookieTokenStore.java @@ -26,13 +26,15 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore { private Request request; private HttpFacade facade; private KeycloakDeployment deployment; + private GenericPrincipalFactory principalFactory; private KeycloakPrincipal authenticatedPrincipal; - public CatalinaCookieTokenStore(Request request, HttpFacade facade, KeycloakDeployment deployment) { + public CatalinaCookieTokenStore(Request request, HttpFacade facade, KeycloakDeployment deployment, GenericPrincipalFactory principalFactory) { this.request = request; this.facade = facade; this.deployment = deployment; + this.principalFactory = principalFactory; } @@ -55,7 +57,7 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore { securityContext.setCurrentRequestInfo(deployment, this); Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext); - GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), authenticatedPrincipal, roles, securityContext); + GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), authenticatedPrincipal, roles, securityContext); request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext); request.setUserPrincipal(principal); diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java index 7121d7f9a7..cf76d13740 100755 --- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java +++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java @@ -2,6 +2,7 @@ package org.keycloak.adapters.tomcat; import org.keycloak.KeycloakSecurityContext; import org.keycloak.adapters.HttpFacade; +import org.keycloak.util.ServerCookie; import javax.security.cert.X509Certificate; import javax.servlet.http.HttpServletResponse; @@ -117,13 +118,10 @@ public class CatalinaHttpFacade implements HttpFacade { @Override public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) { - javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie(name, value); - if (domain != null) cookie.setDomain(domain); - if (path != null) cookie.setPath(path); - if (secure) cookie.setSecure(true); - if (httpOnly) cookie.setHttpOnly(httpOnly); - cookie.setMaxAge(maxAge); - response.addCookie(cookie); + StringBuffer cookieBuf = new StringBuffer(); + ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, null, maxAge, secure, httpOnly); + String cookie = cookieBuf.toString(); + response.addHeader("Set-Cookie", cookie); } @Override diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java index 4c335c9958..fdfe16f493 100755 --- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java +++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java @@ -29,11 +29,13 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator { private static final Logger log = Logger.getLogger(""+CatalinaRequestAuthenticator.class); protected AbstractKeycloakAuthenticatorValve valve; protected Request request; + protected GenericPrincipalFactory principalFactory; public CatalinaRequestAuthenticator(KeycloakDeployment deployment, AbstractKeycloakAuthenticatorValve valve, AdapterTokenStore tokenStore, CatalinaHttpFacade facade, - Request request) { + Request request, + GenericPrincipalFactory principalFactory) { super(facade, deployment, tokenStore, request.getConnector().getRedirectPort()); this.valve = valve; this.request = request; @@ -90,7 +92,7 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator { if (log.isLoggable(Level.FINE)) { log.fine("Completing bearer authentication. Bearer roles: " + roles); } - Principal generalPrincipal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), principal, roles, securityContext); + Principal generalPrincipal = principalFactory.createPrincipal(request.getContext().getRealm(), principal, roles, securityContext); request.setUserPrincipal(generalPrincipal); request.setAuthType("KEYCLOAK"); request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext); diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java index 7fdf280838..761a1d5d86 100755 --- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java +++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java @@ -23,11 +23,13 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore { private Request request; private KeycloakDeployment deployment; private CatalinaUserSessionManagement sessionManagement; + protected GenericPrincipalFactory principalFactory; - public CatalinaSessionTokenStore(Request request, KeycloakDeployment deployment, CatalinaUserSessionManagement sessionManagement) { + public CatalinaSessionTokenStore(Request request, KeycloakDeployment deployment, CatalinaUserSessionManagement sessionManagement, GenericPrincipalFactory principalFactory) { this.request = request; this.deployment = deployment; this.sessionManagement = sessionManagement; + this.principalFactory = principalFactory; } @Override @@ -87,7 +89,7 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore { public void saveAccountInfo(KeycloakAccount account) { RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext)account.getKeycloakSecurityContext(); Set roles = account.getRoles(); - GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), account.getPrincipal(), roles, securityContext); + GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), roles, securityContext); Session session = request.getSessionInternal(true); session.setPrincipal(principal); diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSecurityContextHelper.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java similarity index 68% rename from integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSecurityContextHelper.java rename to integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java index e1795f62be..4ff09f7ce2 100755 --- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSecurityContextHelper.java +++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java @@ -18,24 +18,9 @@ import java.util.Set; * @author Davide Ungari * @version $Revision: 1 $ */ -public class CatalinaSecurityContextHelper { +public abstract class GenericPrincipalFactory { + public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set roleSet, final KeycloakSecurityContext securityContext) { -// KeycloakAccount account = new KeycloakAccount() { -// @Override -// public Principal getPrincipal() { -// return identity; -// } -// -// @Override -// public Set getRoles() { -// return roleSet; -// } -// -// @Override -// public KeycloakSecurityContext getKeycloakSecurityContext() { -// return securityContext; -// } -// }; Subject subject = new Subject(); Set principals = subject.getPrincipals(); principals.add(identity); @@ -44,14 +29,6 @@ public class CatalinaSecurityContextHelper { Group group = roleSets[g]; String name = group.getName(); Group subjectGroup = createGroup(name, principals); -// if (subjectGroup instanceof NestableGroup) { -// /* A NestableGroup only allows Groups to be added to it so we -// need to add a SimpleGroup to subjectRoles to contain the roles -// */ -// SimpleGroup tmp = new SimpleGroup("Roles"); -// subjectGroup.addMember(tmp); -// subjectGroup = tmp; -// } // Copy the group members to the Subject group Enumeration members = group.members(); while (members.hasMoreElements()) { @@ -60,23 +37,15 @@ public class CatalinaSecurityContextHelper { } } - // add the CallerPrincipal group if none has been added in getRoleSets -// Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP); -// callerGroup.addMember(identity); -// principals.add(callerGroup); -// SecurityContext sc = SecurityContextAssociation.getSecurityContext(); -// Principal userPrincipal = getPrincipal(subject); -// sc.getUtil().createSubjectInfo(userPrincipal, account, subject); -// List rolesAsStringList = new ArrayList(); -// rolesAsStringList.addAll(roleSet); -// Principal userPrincipal = getPrincipal(subject); List rolesAsStringList = new ArrayList(); rolesAsStringList.addAll(roleSet); - GenericPrincipal principal = new GenericPrincipal(userPrincipal.getName(), null, rolesAsStringList, userPrincipal, null); + GenericPrincipal principal = createPrincipal(userPrincipal, rolesAsStringList); return principal; } + protected abstract GenericPrincipal createPrincipal(Principal userPrincipal, List roles); + /** * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is * considered or the single subject inside the CallerPrincipal group. diff --git a/integration/tomcat/tomcat6/pom.xml b/integration/tomcat/tomcat6/pom.xml new file mode 100755 index 0000000000..f38684540d --- /dev/null +++ b/integration/tomcat/tomcat6/pom.xml @@ -0,0 +1,104 @@ + + + + keycloak-parent + org.keycloak + 1.1.0.Beta2-SNAPSHOT + ../../../pom.xml + + 4.0.0 + + keycloak-tomcat6-adapter + Keycloak Tomcat 6 Integration + + 6.0.41 + + + + + + org.jboss.logging + jboss-logging + ${jboss.logging.version} + + + org.keycloak + keycloak-core + ${project.version} + + + org.keycloak + keycloak-adapter-core + ${project.version} + + + org.keycloak + keycloak-tomcat-core-adapter + ${project.version} + + + org.apache.tomcat + tomcat-servlet-api + + + org.apache.tomcat + tomcat-catalina + + + org.apache.tomcat + catalina + + + + + org.apache.httpcomponents + httpclient + ${keycloak.apache.httpcomponents.version} + + + net.iharder + base64 + + + org.bouncycastle + bcprov-jdk16 + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-mapper-asl + + + org.codehaus.jackson + jackson-xc + + + org.apache.tomcat + catalina + ${tomcat.version} + provided + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + diff --git a/integration/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java b/integration/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java new file mode 100755 index 0000000000..fa6ac80b20 --- /dev/null +++ b/integration/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java @@ -0,0 +1,46 @@ +package org.keycloak.adapters.tomcat; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.deploy.LoginConfig; +import org.apache.catalina.realm.GenericPrincipal; + +import javax.servlet.ServletException; +import java.security.Principal; +import java.util.List; + +/** + * Keycloak authentication valve + * + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorValve { + @Override + public boolean authenticate(Request request, Response response, LoginConfig config) throws java.io.IOException { + return authenticateInternal(request, response); + } + + @Override + public void start() throws LifecycleException { + StandardContext standardContext = (StandardContext) context; + standardContext.addLifecycleListener(this); + super.start(); + } + + public void logout(Request request) throws ServletException { + logoutInternal(request); + } + + @Override + protected GenericPrincipalFactory createPrincipalFactory() { + return new GenericPrincipalFactory() { + @Override + protected GenericPrincipal createPrincipal(Principal userPrincipal, List roles) { + return new GenericPrincipal(null, userPrincipal.getName(), null, roles, userPrincipal, null); + } + }; + } +} diff --git a/integration/tomcat/tomcat7/pom.xml b/integration/tomcat/tomcat7/pom.xml index f994ace040..45a5cfc68c 100755 --- a/integration/tomcat/tomcat7/pom.xml +++ b/integration/tomcat/tomcat7/pom.xml @@ -37,6 +37,20 @@ org.keycloak keycloak-tomcat-core-adapter ${project.version} + + + org.apache.tomcat + tomcat-servlet-api + + + org.apache.tomcat + tomcat-catalina + + + org.apache.tomcat + catalina + + org.apache.httpcomponents diff --git a/integration/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java b/integration/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java index 004be82624..700378e23c 100755 --- a/integration/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java +++ b/integration/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java @@ -1,11 +1,15 @@ package org.keycloak.adapters.tomcat; import org.apache.catalina.connector.Request; +import org.apache.catalina.core.StandardContext; import org.apache.catalina.deploy.LoginConfig; +import org.apache.catalina.realm.GenericPrincipal; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.security.Principal; +import java.util.List; /** * Keycloak authentication valve @@ -14,14 +18,26 @@ import java.io.IOException; * @version $Revision: 1 $ */ public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorValve { - @Override public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException { return authenticateInternal(request, response); } - @Override + protected void initInternal() { + StandardContext standardContext = (StandardContext) context; + standardContext.addLifecycleListener(this); + } + public void logout(Request request) throws ServletException { logoutInternal(request); - super.logout(request); + } + + @Override + protected GenericPrincipalFactory createPrincipalFactory() { + return new GenericPrincipalFactory() { + @Override + protected GenericPrincipal createPrincipal(Principal userPrincipal, List roles) { + return new GenericPrincipal(userPrincipal.getName(), null, roles, userPrincipal, null); + } + }; } } diff --git a/integration/tomcat/tomcat8/pom.xml b/integration/tomcat/tomcat8/pom.xml index 041e9334b1..668245e10b 100755 --- a/integration/tomcat/tomcat8/pom.xml +++ b/integration/tomcat/tomcat8/pom.xml @@ -45,6 +45,10 @@ org.apache.tomcat tomcat-catalina + + org.apache.tomcat + catalina + diff --git a/integration/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java b/integration/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java index 541baed526..9812c3d2e1 100755 --- a/integration/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java +++ b/integration/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java @@ -1,10 +1,14 @@ package org.keycloak.adapters.tomcat; import org.apache.catalina.connector.Request; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.realm.GenericPrincipal; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.security.Principal; +import java.util.List; /** * Keycloak authentication valve @@ -13,18 +17,26 @@ import java.io.IOException; * @version $Revision: 1 $ */ public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorValve { - @Override public boolean authenticate(Request request, HttpServletResponse response) throws IOException { return authenticateInternal(request, response); } - @Override + protected void initInternal() { + StandardContext standardContext = (StandardContext) context; + standardContext.addLifecycleListener(this); + } + public void logout(Request request) { logoutInternal(request); - try { - super.logout(request); - } catch (Exception e) { - throw new RuntimeException(e); - } + } + + @Override + protected GenericPrincipalFactory createPrincipalFactory() { + return new GenericPrincipalFactory() { + @Override + protected GenericPrincipal createPrincipal(Principal userPrincipal, List roles) { + return new GenericPrincipal(userPrincipal.getName(), null, roles, userPrincipal, null); + } + }; } } diff --git a/services/src/main/java/org/keycloak/services/util/CookieHelper.java b/services/src/main/java/org/keycloak/services/util/CookieHelper.java index 3b30b237ab..00d5156dc9 100755 --- a/services/src/main/java/org/keycloak/services/util/CookieHelper.java +++ b/services/src/main/java/org/keycloak/services/util/CookieHelper.java @@ -2,6 +2,7 @@ package org.keycloak.services.util; import org.jboss.resteasy.spi.HttpResponse; import org.jboss.resteasy.spi.ResteasyProviderFactory; +import org.keycloak.util.ServerCookie; import javax.ws.rs.core.HttpHeaders; diff --git a/testsuite/pom.xml b/testsuite/pom.xml index afcb479477..db0fad4111 100755 --- a/testsuite/pom.xml +++ b/testsuite/pom.xml @@ -26,6 +26,7 @@ integration + tomcat6 tomcat7 tomcat8 jetty/jetty81 diff --git a/testsuite/tomcat6/pom.xml b/testsuite/tomcat6/pom.xml new file mode 100755 index 0000000000..e18f5e677f --- /dev/null +++ b/testsuite/tomcat6/pom.xml @@ -0,0 +1,501 @@ + + + + keycloak-testsuite-pom + org.keycloak + 1.1.0.Beta2-SNAPSHOT + ../pom.xml + + 4.0.0 + + keycloak-testsuite-tomcat6 + Keycloak Tomcat 6 Integration TestSuite + + 6.0.41 + + + + + + org.keycloak + keycloak-dependencies-server-all + ${project.version} + pom + + + org.keycloak + keycloak-admin-client + ${project.version} + + + log4j + log4j + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + + + org.jboss.resteasy + jaxrs-api + ${resteasy.version.latest} + + + org.jboss.resteasy + resteasy-jaxrs + ${resteasy.version.latest} + + + log4j + log4j + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-simple + + + + + org.jboss.resteasy + resteasy-client + ${resteasy.version.latest} + + + org.jboss.resteasy + resteasy-crypto + ${resteasy.version.latest} + + + org.jboss.resteasy + resteasy-multipart-provider + ${resteasy.version.latest} + + + org.jboss.resteasy + resteasy-jackson-provider + ${resteasy.version.latest} + + + org.jboss.resteasy + resteasy-undertow + ${resteasy.version.latest} + + + com.google.zxing + javase + + + org.bouncycastle + bcprov-jdk16 + + + org.apache.httpcomponents + httpclient + ${keycloak.apache.httpcomponents.version} + + + org.keycloak + keycloak-ldap-federation + ${project.version} + + + org.keycloak + keycloak-undertow-adapter + ${project.version} + + + org.keycloak + keycloak-tomcat6-adapter + ${project.version} + + + org.jboss.logging + jboss-logging + + + io.undertow + undertow-servlet + + + io.undertow + undertow-core + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-mapper-asl + + + org.codehaus.jackson + jackson-xc + + + junit + junit + + + org.hamcrest + hamcrest-all + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + + + com.h2database + h2 + + + org.hibernate + hibernate-entitymanager + + + com.icegreen + greenmail + + + org.slf4j + slf4j-api + + + + + org.infinispan + infinispan-core + + + org.seleniumhq.selenium + selenium-java + + + xml-apis + xml-apis + + + org.seleniumhq.selenium + selenium-chrome-driver + + + org.wildfly + wildfly-undertow + ${wildfly.version} + test + + + org.keycloak + keycloak-testsuite-integration + ${project.version} + test + + + org.keycloak + keycloak-testsuite-integration + ${project.version} + test-jar + test + + + org.apache.tomcat + catalina + ${tomcat.version} + + + org.apache.tomcat + coyote + ${tomcat.version} + + + org.apache.tomcat + jasper + ${tomcat.version} + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.source} + ${maven.compiler.target} + + + + org.codehaus.mojo + exec-maven-plugin + + ${project.basedir} + + + + + + + + keycloak-server + + + + org.codehaus.mojo + exec-maven-plugin + + org.keycloak.testutils.KeycloakServer + + + + + + + mail-server + + + + org.codehaus.mojo + exec-maven-plugin + + org.keycloak.testutils.MailServer + + + + + + + totp + + + + org.codehaus.mojo + exec-maven-plugin + + org.keycloak.testutils.TotpGenerator + + + + + + + + jpa + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + jpa + jpa + jpa + jpa + + + + + + + + + mongo + + + localhost + 27018 + keycloak + true + 127.0.0.1 + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + test + integration-test + + test + + + + mongo + mongo + mongo + mongo + ${keycloak.connectionsMongo.host} + ${keycloak.connectionsMongo.port} + ${keycloak.connectionsMongo.db} + ${keycloak.connectionsMongo.clearOnStartup} + ${keycloak.connectionsMongo.bindIp} + + + + + default-test + + true + + + + + + + + com.github.joelittlejohn.embedmongo + embedmongo-maven-plugin + + + start-mongodb + pre-integration-test + + start + + + ${keycloak.connectionsMongo.port} + file + ${project.build.directory}/mongodb.log + ${keycloak.connectionsMongo.bindIp} + + + + stop-mongodb + post-integration-test + + stop + + + + + + + + + + + infinispan + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + infinispan + infinispan + infinispan + + + + + + + + + + + + keycloak.connectionsJpa.driver + com.mysql.jdbc.Driver + + + mysql + + + mysql + mysql-connector-java + ${mysql.version} + + + + + + + + + keycloak.connectionsJpa.driver + org.postgresql.Driver + + + postgresql + + + org.postgresql + postgresql + ${postgresql.version} + + + + + + clean-jpa + + + + org.liquibase + liquibase-maven-plugin + + META-INF/jpa-changelog-master.xml + + ${keycloak.connectionsJpa.url} + ${keycloak.connectionsJpa.driver} + ${keycloak.connectionsJpa.user} + ${keycloak.connectionsJpa.password} + + false + + + + clean-jpa + clean + + dropAll + + + + + + + + + diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java new file mode 100755 index 0000000000..ca7b77c085 --- /dev/null +++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java @@ -0,0 +1,131 @@ +package org.keycloak.testsuite; + +import org.apache.catalina.Engine; +import org.apache.catalina.Host; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.Embedded; +import org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TomcatServer { + private Embedded server; + private int port; + private boolean isRunning; + + private static final Logger LOG = LoggerFactory.getLogger(TomcatServer.class); + private static final boolean isInfo = LOG.isInfoEnabled(); + + + /** + * Create a new Tomcat embedded server instance. Setup looks like: + *

+     *    
+     *        
+     *        
+     *                
+     *            
+     *        
+     *    
+     * 
+ * & will be created automcatically. We need to hook the remaining to an {@link Embedded} instnace + * + * @param contextPath Context path for the application + * @param port Port number to be used for the embedded Tomcat server + * @param appBase Path to the Application files (for Maven based web apps, in general: /src/main/) + * @param shutdownHook If true, registers a server' shutdown hook with JVM. This is useful to shutdown the server + * in erroneous cases. + * @throws Exception + */ + public TomcatServer(String contextPath, int port, String appBase, boolean shutdownHook) { + if (contextPath == null || appBase == null || appBase.length() == 0) { + throw new IllegalArgumentException("Context path or appbase should not be null"); + } + if (!contextPath.startsWith("/")) { + contextPath = "/" + contextPath; + } + + this.port = port; + + server = new Embedded(); + server.setName("TomcatEmbeddedServer"); + + Host localHost = server.createHost("localhost", appBase); + localHost.setAutoDeploy(false); + + StandardContext rootContext = (StandardContext) server.createContext(contextPath, "webapp"); + KeycloakAuthenticatorValve valve = new KeycloakAuthenticatorValve(); + rootContext.addValve(valve); + //rootContext.addLifecycleListener(valve); + rootContext.setDefaultWebXml("web.xml"); + localHost.addChild(rootContext); + + Engine engine = server.createEngine(); + engine.setDefaultHost(localHost.getName()); + engine.setName("TomcatEngine"); + engine.addChild(localHost); + + server.addEngine(engine); + + Connector connector = server.createConnector(localHost.getName(), port, false); + server.addConnector(connector); + + // register shutdown hook + if (shutdownHook) { + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + if (isRunning) { + if (isInfo) LOG.info("Stopping the Tomcat server, through shutdown hook"); + try { + if (server != null) { + server.stop(); + } + } catch (LifecycleException e) { + LOG.error("Error while stopping the Tomcat server, through shutdown hook", e); + } + } + } + }); + } + + } + + /** + * Start the tomcat embedded server + */ + public void start() throws LifecycleException { + if (isRunning) { + LOG.warn("Tomcat server is already running @ port={}; ignoring the start", port); + return; + } + + if (isInfo) LOG.info("Starting the Tomcat server @ port={}", port); + + server.setAwait(true); + server.start(); + isRunning = true; + } + + /** + * Stop the tomcat embedded server + */ + public void stop() throws LifecycleException { + if (!isRunning) { + LOG.warn("Tomcat server is not running @ port={}", port); + return; + } + + if (isInfo) LOG.info("Stopping the Tomcat server"); + + server.stop(); + isRunning = false; + } + + public boolean isRunning() { + return isRunning; + } + +} \ No newline at end of file diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java new file mode 100755 index 0000000000..1b36bde717 --- /dev/null +++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java @@ -0,0 +1,187 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite; + +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.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.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.regex.Matcher; + +/** + * @author Stian Thorgersen + */ +public class TomcatTest { + static String logoutUri = OpenIDConnectService.logoutUrl(UriBuilder.fromUri("http://localhost:8081/auth")) + .queryParam(OAuth2Constants.REDIRECT_URI, "http://localhost:8080/customer-portal").build("demo").toString(); + + @ClassRule + public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() { + @Override + protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) { + RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/tomcat-test/demorealm.json"), RealmRepresentation.class); + RealmModel realm = manager.importRealm(representation); + } + }; + + public static class SendUsernameServlet extends HttpServlet { + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + resp.setContentType("text/plain"); + OutputStream stream = resp.getOutputStream(); + Principal principal = req.getUserPrincipal(); + if (principal == null) { + stream.write("null".getBytes()); + return; + } + String name = principal.getName(); + stream.write(name.getBytes()); + stream.write("\n".getBytes()); + KeycloakSecurityContext context = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName()); + stream.write(context.getIdToken().getName().getBytes()); + stream.write("\n".getBytes()); + stream.write(logoutUri.getBytes()); + + } + @Override + protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + doGet(req, resp); + } + } + + static TomcatServer tomcat = null; + + @BeforeClass + public static void initTomcat() throws Exception { + URL dir = TomcatTest.class.getResource("/tomcat-test/webapp/META-INF/context.xml"); + String baseDir = new File(dir.getFile()).getParentFile().getParentFile().getParentFile().toString(); + System.out.println("Tomcat basedir: " + baseDir); + tomcat = new TomcatServer("/customer-portal", 8080, baseDir, false); + + + tomcat.start(); + //tomcat.getServer().await(); + } + + @AfterClass + public static void shutdownTomcat() throws Exception { + tomcat.stop(); + } + + @Rule + public WebRule webRule = new WebRule(this); + @WebResource + protected WebDriver driver; + @WebResource + protected LoginPage loginPage; + + public static final String LOGIN_URL = OpenIDConnectService.loginPageUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build("demo").toString(); + + @Ignore + @Test + public void testServer() throws Exception{ + Thread.sleep(1000000000); + } + + @Test + public void testLoginSSOAndLogout() throws Exception { + driver.navigate().to("http://localhost:8080/customer-portal"); + System.out.println("Current url: " + driver.getCurrentUrl()); + //System.out.println(driver.getPageSource()); + Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL)); + loginPage.login("bburke@redhat.com", "password"); + System.out.println("Current url: " + driver.getCurrentUrl()); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8080/customer-portal"); + String pageSource = driver.getPageSource(); + System.out.println(pageSource); + Assert.assertTrue(pageSource.contains("Bill Burke")); + + // test logout + + String logoutUri = OpenIDConnectService.logoutUrl(UriBuilder.fromUri("http://localhost:8081/auth")) + .queryParam(OAuth2Constants.REDIRECT_URI, "http://localhost:8080/customer-portal").build("demo").toString(); + driver.navigate().to(logoutUri); + Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL)); + driver.navigate().to("http://localhost:8080/customer-portal"); + String currentUrl = driver.getCurrentUrl(); + Assert.assertTrue(currentUrl.startsWith(LOGIN_URL)); + + + } + + @Test + @Ignore + public void runit() throws Exception { + Thread.sleep(10000000); + } + + + private static String getBaseDirectory() { + String dirPath = null; + String relativeDirPath = "testsuite" + File.separator + "tomcat6" + File.separator + "target"; + + if (System.getProperties().containsKey("maven.home")) { + dirPath = System.getProperty("user.dir").replaceFirst("testsuite.tomcat6.*", Matcher.quoteReplacement(relativeDirPath)); + } else { + for (String c : System.getProperty("java.class.path").split(File.pathSeparator)) { + if (c.contains(File.separator + "testsuite" + File.separator + "tomcat6")) { + dirPath = c.replaceFirst("testsuite.tomcat6.*", Matcher.quoteReplacement(relativeDirPath)); + break; + } + } + } + + String absolutePath = new File(dirPath).getAbsolutePath(); + return absolutePath; + } + + + + +} diff --git a/testsuite/tomcat6/src/test/resources/tomcat-test/demorealm.json b/testsuite/tomcat6/src/test/resources/tomcat-test/demorealm.json new file mode 100755 index 0000000000..a4a6ec9903 --- /dev/null +++ b/testsuite/tomcat6/src/test/resources/tomcat-test/demorealm.json @@ -0,0 +1,58 @@ +{ + "id": "demo", + "realm": "demo", + "enabled": true, + "accessTokenLifespan": 3000, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 6000, + "sslRequired": "external", + "registrationAllowed": false, + "social": false, + "passwordCredentialGrantAllowed": true, + "updateProfileOnInitialSocialLogin": false, + "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=", + "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "firstName": "Bill", + "lastName": "Burke", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "user", "admin" ], + "applicationRoles": { + "account": [ "manage-account" ] + } + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "User privileges" + }, + { + "name": "admin", + "description": "Administrator privileges" + } + ] + }, + "applications": [ + { + "name": "customer-portal", + "enabled": true, + "fullScopeAllowed": true, + "adminUrl": "http://localhost:8080/customer-portal", + "baseUrl": "http://localhost:8080/customer-portal", + "redirectUris": [ + "http://localhost:8080/customer-portal/*" + ], + "secret": "password" + } + ] +} diff --git a/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/META-INF/context.xml b/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/META-INF/context.xml new file mode 100755 index 0000000000..6f24639879 --- /dev/null +++ b/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/META-INF/context.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/WEB-INF/keycloak.json b/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/WEB-INF/keycloak.json new file mode 100755 index 0000000000..4e2fe1e556 --- /dev/null +++ b/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/WEB-INF/keycloak.json @@ -0,0 +1,10 @@ +{ + "realm": "demo", + "resource": "customer-portal", + "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", + "auth-server-url": "http://localhost:8081/auth", + "ssl-required" : "external", + "credentials": { + "secret": "password" + } +} diff --git a/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/WEB-INF/web.xml new file mode 100755 index 0000000000..12416c8b73 --- /dev/null +++ b/testsuite/tomcat6/src/test/resources/tomcat-test/webapp/WEB-INF/web.xml @@ -0,0 +1,40 @@ + + + + adapter-test + + + SendUsername + org.keycloak.testsuite.TomcatTest$SendUsernameServlet + + + + SendUsername + /* + + + + + Admins + /* + + + admin + + + + + BASIC + demo + + + + admin + + + user + +