diff --git a/core/src/main/java/org/keycloak/util/CertificateUtils.java b/core/src/main/java/org/keycloak/util/CertificateUtils.java index ae18376c5c..073ef3f8e8 100755 --- a/core/src/main/java/org/keycloak/util/CertificateUtils.java +++ b/core/src/main/java/org/keycloak/util/CertificateUtils.java @@ -19,6 +19,9 @@ import java.util.Date; * @version $Revision: 1 $ */ public class CertificateUtils { + static { + BouncyIntegration.init(); + } public static X509Certificate generateV3Certificate(KeyPair keyPair, PrivateKey caPrivateKey, X509Certificate caCert, String subject) throws Exception { X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); diff --git a/distribution/pom.xml b/distribution/pom.xml index de6a724d2c..0ca3283983 100755 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -39,6 +39,7 @@ theme-template-zip war-zip war-dist + proxy appliance-dist src-dist diff --git a/distribution/proxy/assembly.xml b/distribution/proxy/assembly.xml new file mode 100755 index 0000000000..f5f9a80af4 --- /dev/null +++ b/distribution/proxy/assembly.xml @@ -0,0 +1,30 @@ + + war-dist + + + zip + + false + + + + false + true + true + + org.keycloak:launcher + + ${artifact.artifactId}.${artifact.extension} + bin + + + false + true + true + + org.keycloak:keycloak-proxy-server + + lib + + + diff --git a/distribution/proxy/pom.xml b/distribution/proxy/pom.xml new file mode 100755 index 0000000000..e386059541 --- /dev/null +++ b/distribution/proxy/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + keycloak-parent + org.keycloak + 1.1.0.Beta2-SNAPSHOT + ../../pom.xml + + + keycloak-proxy-dist + pom + Proxy Distro + + + + + org.keycloak + launcher + ${project.version} + + + org.keycloak + keycloak-proxy-server + ${project.version} + + + + + + maven-assembly-plugin + 2.4 + + + assemble + package + + single + + + + assembly.xml + + + target + + + target/assembly/work + + false + + + + + + + + diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowUserSessionManagement.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowUserSessionManagement.java index cc0a7c540a..6165d76379 100755 --- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowUserSessionManagement.java +++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowUserSessionManagement.java @@ -16,21 +16,15 @@ */ package org.keycloak.adapters.undertow; -import io.undertow.security.api.AuthenticatedSessionManager; import io.undertow.server.HttpServerExchange; import io.undertow.server.session.Session; import io.undertow.server.session.SessionConfig; import io.undertow.server.session.SessionListener; import io.undertow.server.session.SessionManager; -import io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler; import org.jboss.logging.Logger; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; /** * Manages relationship to users and sessions so that forced admin logout can be implemented @@ -40,7 +34,6 @@ import java.util.concurrent.ConcurrentHashMap; */ public class UndertowUserSessionManagement implements SessionListener { private static final Logger log = Logger.getLogger(UndertowUserSessionManagement.class); - private static final String AUTH_SESSION_NAME = CachedAuthenticatedSessionHandler.class.getName() + ".AuthenticatedSession"; protected volatile boolean registered; public void login(SessionManager manager) { @@ -67,7 +60,7 @@ public class UndertowUserSessionManagement implements SessionListener { log.debug("logoutHttpSession: " + httpSessionId); Session session = getSessionById(manager, httpSessionId); try { - session.invalidate(null); + if (session != null) session.invalidate(null); } catch (Exception e) { log.warnf("Session %s not present or already invalidated.", httpSessionId); } @@ -115,16 +108,6 @@ public class UndertowUserSessionManagement implements SessionListener { @Override public void sessionDestroyed(Session session, HttpServerExchange exchange, SessionDestroyedReason reason) { - // Look up the single session id associated with this session (if any) - String username = getUsernameFromSession(session); - log.debugf("Session destroyed for user: %s, sessionId: %s", username, session.getId()); - } - - protected String getUsernameFromSession(Session session) { - AuthenticatedSessionManager.AuthenticatedSession authSession = (AuthenticatedSessionManager.AuthenticatedSession) session.getAttribute(AUTH_SESSION_NAME); - if (authSession == null) return null; - return authSession.getAccount().getPrincipal().getName(); - } diff --git a/pom.xml b/pom.xml index ba351f100e..1bf8595a03 100755 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ events model integration - proxy/proxy-server + proxy picketlink federation services diff --git a/proxy/launcher/pom.xml b/proxy/launcher/pom.xml new file mode 100755 index 0000000000..d70d14d699 --- /dev/null +++ b/proxy/launcher/pom.xml @@ -0,0 +1,43 @@ + + + + keycloak-parent + org.keycloak + 1.1.0.Beta2-SNAPSHOT + ../../pom.xml + + 4.0.0 + + launcher + Keycloak Launcher + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.keycloak.Launcher + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + diff --git a/proxy/launcher/src/main/java/org/keycloak/Launcher.java b/proxy/launcher/src/main/java/org/keycloak/Launcher.java new file mode 100755 index 0000000000..56eab1e5ba --- /dev/null +++ b/proxy/launcher/src/main/java/org/keycloak/Launcher.java @@ -0,0 +1,66 @@ +package org.keycloak; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class Launcher { + + public static File getHome() { + String launcherPath = Launcher.class.getName().replace('.', '/') + ".class"; + URL jarfile = Launcher.class.getClassLoader().getResource(launcherPath); + if (jarfile != null) { + Matcher m = Pattern.compile("jar:(file:.*)!/" + launcherPath).matcher(jarfile.toString()); + if (m.matches()) { + try { + File jarPath = new File(new URI(m.group(1))); + File libPath = jarPath.getParentFile().getParentFile(); + System.out.println("Home directory: " + libPath.toString()); + if (!libPath.exists()) { + System.exit(1); + + } + return libPath; + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + } else { + System.err.println("jar file null: " + launcherPath); + } + return null; + } + + public static void main(String[] args) throws Exception { + + File home = getHome(); + File lib = new File(home, "lib"); + if (!lib.exists()) { + System.err.println("Could not find lib directory: " + lib.toString()); + System.exit(1); + } + List jars = new ArrayList(); + for (File file : lib.listFiles()) { + jars.add(file.toURI().toURL()); + } + URL[] urls = jars.toArray(new URL[jars.size()]); + URLClassLoader loader = new URLClassLoader(urls, Launcher.class.getClassLoader()); + + Class mainClass = loader.loadClass("org.keycloak.proxy.Main"); + Method mainMethod = null; + for (Method m : mainClass.getMethods()) if (m.getName().equals("main")) { mainMethod = m; break; } + Object obj = args; + mainMethod.invoke(null, obj); + } +} diff --git a/proxy/pom.xml b/proxy/pom.xml new file mode 100755 index 0000000000..b9d77ef887 --- /dev/null +++ b/proxy/pom.xml @@ -0,0 +1,31 @@ + + + keycloak-parent + org.keycloak + 1.1.0.Beta2-SNAPSHOT + ../pom.xml + + Model Parent + + 4.0.0 + + keycloak-proxy-pom + pom + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + launcher + proxy-server + + diff --git a/proxy/proxy-server/pom.xml b/proxy/proxy-server/pom.xml index 4b4d12adb9..ddc4a54eb3 100755 --- a/proxy/proxy-server/pom.xml +++ b/proxy/proxy-server/pom.xml @@ -18,7 +18,6 @@ org.jboss.logging jboss-logging ${jboss.logging.version} - provided org.keycloak @@ -63,7 +62,6 @@ io.undertow undertow-core - provided junit diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintMatcherHandler.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintMatcherHandler.java index 9eb49dbcd4..2fd260bdba 100755 --- a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintMatcherHandler.java +++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintMatcherHandler.java @@ -4,6 +4,7 @@ import io.undertow.security.handlers.AuthenticationConstraintHandler; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; import io.undertow.util.AttachmentKey; +import org.jboss.logging.Logger; import org.keycloak.KeycloakSecurityContext; /** @@ -11,6 +12,7 @@ import org.keycloak.KeycloakSecurityContext; * @version $Revision: 1 $ */ public class ConstraintMatcherHandler implements HttpHandler { + protected static Logger log = Logger.getLogger(ConstraintMatcherHandler.class); public static final AttachmentKey CONSTRAINT_KEY = AttachmentKey.create(SingleConstraintMatch.class); protected SecurityPathMatches matcher; protected HttpHandler securedHandler; @@ -26,6 +28,7 @@ public class ConstraintMatcherHandler implements HttpHandler { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { + log.debugv("ConstraintMatcherHandler: {0}", exchange.getRelativePath()); SingleConstraintMatch match = matcher.getSecurityInfo(exchange.getRelativePath(), exchange.getRequestMethod().toString()).getMergedConstraint(); if (match == null || (match.getRequiredRoles().isEmpty() && match.getEmptyRoleSemantic() == SecurityInfo.EmptyRoleSemantic.PERMIT)) { unsecuredHandler.handleRequest(exchange); @@ -44,6 +47,7 @@ public class ConstraintMatcherHandler implements HttpHandler { } return; } + log.debug("found constraint"); exchange.getSecurityContext().setAuthenticationRequired(); exchange.putAttachment(CONSTRAINT_KEY, match); securedHandler.handleRequest(exchange); diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/Main.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/Main.java new file mode 100755 index 0000000000..69dbbe09dc --- /dev/null +++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/Main.java @@ -0,0 +1,28 @@ +package org.keycloak.proxy; + +import io.undertow.Undertow; + +import java.io.File; +import java.io.FileInputStream; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class Main { + + public static void main(String[] args) throws Exception { + String jsonConfig = "proxy.json"; + if (args.length > 0) jsonConfig = args[0]; + File file = new File(jsonConfig); + if (!file.exists()) { + System.err.println("No proxy config argument and could not find default file proxy.json"); + System.exit(1); + return; + } + FileInputStream fis = new FileInputStream(file); + Undertow proxyServer = ProxyServerBuilder.build(fis); + proxyServer.start(); + + } +} diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java index 3e03c3b7a6..379656b369 100755 --- a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java +++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java @@ -137,6 +137,7 @@ public class ProxyServerBuilder { } public ConstraintBuilder constraint(String pattern) { + log.debugv("add constraint: {0}", pattern); return new ConstraintBuilder(pattern); }