proxy distro

This commit is contained in:
Bill Burke 2014-11-24 18:12:17 -05:00
parent 4bad1fea86
commit d0856e024f
13 changed files with 267 additions and 21 deletions

View file

@ -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();

View file

@ -39,6 +39,7 @@
<module>theme-template-zip</module>
<module>war-zip</module>
<module>war-dist</module>
<module>proxy</module>
<module>appliance-dist</module>
<module>src-dist</module>
</modules>

30
distribution/proxy/assembly.xml Executable file
View file

@ -0,0 +1,30 @@
<assembly>
<id>war-dist</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
<useTransitiveDependencies>true</useTransitiveDependencies>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>org.keycloak:launcher</include>
</includes>
<outputFileNameMapping>${artifact.artifactId}.${artifact.extension}</outputFileNameMapping>
<outputDirectory>bin</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>false</unpack>
<useTransitiveDependencies>true</useTransitiveDependencies>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>org.keycloak:keycloak-proxy-server</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>

58
distribution/proxy/pom.xml Executable file
View file

@ -0,0 +1,58 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Beta2-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>keycloak-proxy-dist</artifactId>
<packaging>pom</packaging>
<name>Proxy Distro</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>launcher</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-proxy-server</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<outputDirectory>
target
</outputDirectory>
<workDirectory>
target/assembly/work
</workDirectory>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -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();
}

View file

@ -108,7 +108,7 @@
<module>events</module>
<module>model</module>
<module>integration</module>
<module>proxy/proxy-server</module>
<module>proxy</module>
<module>picketlink</module>
<module>federation</module>
<module>services</module>

43
proxy/launcher/pom.xml Executable file
View file

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Beta2-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>launcher</artifactId>
<name>Keycloak Launcher</name>
<description/>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.keycloak.Launcher</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @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<URL> jars = new ArrayList<URL>();
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);
}
}

31
proxy/pom.xml Executable file
View file

@ -0,0 +1,31 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.1.0.Beta2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Model Parent</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-proxy-pom</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>launcher</module>
<module>proxy-server</module>
</modules>
</project>

View file

@ -18,7 +18,6 @@
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
@ -63,7 +62,6 @@
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>

View file

@ -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<SingleConstraintMatch> 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);

View file

@ -0,0 +1,28 @@
package org.keycloak.proxy;
import io.undertow.Undertow;
import java.io.File;
import java.io.FileInputStream;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @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();
}
}

View file

@ -137,6 +137,7 @@ public class ProxyServerBuilder {
}
public ConstraintBuilder constraint(String pattern) {
log.debugv("add constraint: {0}", pattern);
return new ConstraintBuilder(pattern);
}