keycloak-uncached
Changes
distribution/pom.xml 1(+1 -0)
distribution/proxy/assembly.xml 30(+30 -0)
distribution/proxy/pom.xml 58(+58 -0)
docbook/reference/en/en-US/modules/proxy.xml 277(+277 -0)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowUserSessionManagement.java 19(+1 -18)
pom.xml 2(+1 -1)
proxy/launcher/pom.xml 43(+43 -0)
proxy/pom.xml 31(+31 -0)
proxy/proxy-server/pom.xml 2(+0 -2)
Details
diff --git a/core/src/main/java/org/keycloak/util/CertificateUtils.java b/core/src/main/java/org/keycloak/util/CertificateUtils.java
index ae18376..073ef3f 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();
distribution/pom.xml 1(+1 -0)
diff --git a/distribution/pom.xml b/distribution/pom.xml
index de6a724..0ca3283 100755
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -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>
distribution/proxy/assembly.xml 30(+30 -0)
diff --git a/distribution/proxy/assembly.xml b/distribution/proxy/assembly.xml
new file mode 100755
index 0000000..f5f9a80
--- /dev/null
+++ b/distribution/proxy/assembly.xml
@@ -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>
distribution/proxy/pom.xml 58(+58 -0)
diff --git a/distribution/proxy/pom.xml b/distribution/proxy/pom.xml
new file mode 100755
index 0000000..e386059
--- /dev/null
+++ b/distribution/proxy/pom.xml
@@ -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>
diff --git a/docbook/reference/en/en-US/master.xml b/docbook/reference/en/en-US/master.xml
index c9a6f21..e6cd953 100755
--- a/docbook/reference/en/en-US/master.xml
+++ b/docbook/reference/en/en-US/master.xml
@@ -39,6 +39,7 @@
<!ENTITY Clustering SYSTEM "modules/clustering.xml">
<!ENTITY ApplicationClustering SYSTEM "modules/application-clustering.xml">
<!ENTITY MultiTenancy SYSTEM "modules/multi-tenancy.xml">
+ <!ENTITY Proxy SYSTEM "modules/proxy.xml">
]>
<book>
@@ -135,6 +136,7 @@ This one is short
&SecurityVulnerabilities;
&Clustering;
&ApplicationClustering;
+ &Proxy;
&Migration;
</book>
docbook/reference/en/en-US/modules/proxy.xml 277(+277 -0)
diff --git a/docbook/reference/en/en-US/modules/proxy.xml b/docbook/reference/en/en-US/modules/proxy.xml
new file mode 100755
index 0000000..62848ec
--- /dev/null
+++ b/docbook/reference/en/en-US/modules/proxy.xml
@@ -0,0 +1,277 @@
+<chapter id="proxy">
+ <title>Keycloak Security Proxy</title>
+ <para>
+ Keycloak has an HTTP(S) proxy that you can put in front of web applications and services where it is not possible
+ to install the keycloak adapter. You can set up URL filters so that certain URLs are secured either by browser login
+ and/or bearer token authentication. You can also define role constraints for URL patterns within your applications.
+ </para>
+ <section>
+ <title>Proxy Install and Run</title>
+ <para>Download the keycloak proxy distribution from the Keycloak download pages and unzip it.
+<programlisting>
+$ unzip keycloak-proxy-dist.zip
+</programlisting>
+ </para>
+ <para>
+ To run it you must have a proxy config file (which we'll discuss in a moment).
+<programlisting>
+$ java -jar bin/launcher.jar [your-config.json]
+</programlisting>
+ </para>
+ <para>
+ If you do not specify a path to the proxy config file, the launcher will look in the current working directory
+ for the file named <literal>proxy.json</literal>
+ </para>
+ </section>
+ <section>
+ <title>Proxy Configuration</title>
+ <para>
+ Here's an example configuration file.
+<programlisting><![CDATA[
+{
+ "target-url": "http://localhost:8082",
+ "bind-address": "localhost",
+ "http-port": "8080",
+ "https-port": "8443",
+ "keystore": "classpath:ssl.jks",
+ "keystore-password": "password",
+ "key-password": "password",
+ "applications": [
+ {
+ "base-path": "/customer-portal",
+ "error-page": "/error.html",
+ "adapter-config": {
+ "realm": "demo",
+ "resource": "customer-portal",
+ "realm-public-key": "MIGfMA0GCSqGSIb",
+ "auth-server-url": "http://localhost:8081/auth",
+ "ssl-required" : "external",
+ "principal-attribute": "name",
+ "credentials": {
+ "secret": "password"
+ }
+ }
+ ,
+ "constraints": [
+ {
+ "pattern": "/users/*",
+ "roles-allowed": [
+ "user"
+ ]
+ },
+ {
+ "pattern": "/admins/*",
+ "roles-allowed": [
+ "admin"
+ ]
+ },
+ {
+ "pattern": "/users/permit",
+ "permit": true
+ },
+ {
+ "pattern": "/users/deny",
+ "deny": true
+ }
+ ]
+ }
+ ]
+}]]>
+</programlisting>
+ </para>
+ <section>
+ <title>Basic Config</title>
+ <para>
+ The basic configuration options for the server are as follows:
+ <variablelist>
+ <varlistentry>
+ <term>target-url</term>
+ <listitem>
+ <para>
+ The URL this server is proxying <emphasis>REQUIRED.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>bind-address</term>
+ <listitem>
+ <para>
+ DNS name or IP address to bind the proxy server's sockets to.
+ <emphasis>OPTIONAL.</emphasis>. The default value is <emphasis>localhost</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>http-port</term>
+ <listitem>
+ <para>
+ Port to listen for HTTP requests. If you do not specify this value, then the proxy will
+ not listen for regular HTTP requests.
+ <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>https-port</term>
+ <listitem>
+ <para>
+ Port to listen for HTTPS requests. If you do not specify this value, then the proxy will
+ not listen for HTTPS requests.
+ <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>keystore</term>
+ <listitem>
+ <para>
+ Path to a Java keystore file that contains private key and certificate for the server to be
+ able to handle HTTPS requests. Can be a file path, or, if you prefix it with <literal>classpath:</literal>
+ it will look for this file in the classpath.
+ <emphasis>OPTIONAL.</emphasis>. If you have enabled HTTPS, but have not defined a keystore, the proxy
+ will auto-generate a self-signed certificate and use that.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>buffer-size</term>
+ <listitem>
+ <para>
+ HTTP server socket buffer size. Usually the default is good enough. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>buffers-per-region</term>
+ <listitem>
+ <para>
+ HTTP server socket buffers per region. Usually the default is good enough. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>io-threads</term>
+ <listitem>
+ <para>
+ Number of threads to handle IO. Usually default is good enough. <emphasis>OPTIONAL.</emphasis>.
+ The default is the number of available processors * 2.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>worker-threads</term>
+ <listitem>
+ <para>
+ Number of threads to handle requests. Usually the default is good enough. <emphasis>OPTIONAL.</emphasis>.
+ The default is the number of available processors * 16.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </section>
+ <section>
+ <title>Application Config</title>
+ <para>
+ Next under the <literal>applications</literal> array attribute, you can define one or more applications per host you are proxying.
+ <variablelist>
+ <varlistentry>
+ <term>base-path</term>
+ <listitem>
+ <para>
+ The base context root for the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>error-page</term>
+ <listitem>
+ <para>
+ If the proxy has an error, it will display the target application's error page relative URL <emphasis>OPTIONAL.</emphasis>.
+ This is a relative path to the base-path. In the example above it would be <literal>/customer-portal/error.html</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>adapter-config</term>
+ <listitem>
+ <para>
+ <emphasis>REQUIRED.</emphasis>. Same configuration as any other keycloak adapter. See <link linkend='adapter-config'>Adapter Config</link>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <section>
+ <title>Constraint Config</title>
+
+ <para>
+ Next under each application you can define one or more constraints in the <literal>constraints</literal> array attribute.
+ A constraint defines a URL pattern relative to the base-path. You can deny, permit, or require authentication for
+ a specific URL pattern. You can specify roles allowed for that path as well. More specific constraints will take
+ precedence over more general ones.
+ <variablelist>
+ <varlistentry>
+ <term>pattern</term>
+ <listitem>
+ <para>
+ URL pattern to match relative to the base-path of the application. Must start with '/' <emphasis>REQUIRED.</emphasis>.
+ You may only have one wildcard and it must come at the end of the pattern. Valid <literal>/foo/bar/*</literal> and <literal>/foo/*.txt</literal>
+ Not valid: <literal>/*/foo/*</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>roles-allowed</term>
+ <listitem>
+ <para>
+ Array of strings of roles allowed to access this url pattern. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>methods</term>
+ <listitem>
+ <para>
+ Array of strings of HTTP methods that will exclusively match this pattern and HTTP request. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>excluded-methods</term>
+ <listitem>
+ <para>
+ Array of strings of HTTP methods that will be ignored when match this pattern. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>deny</term>
+ <listitem>
+ <para>
+ Deny all access to this URL pattern. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>permit</term>
+ <listitem>
+ <para>
+ Permit all access without requiring authentication or a role mapping. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>authenticate</term>
+ <listitem>
+ <para>
+ Require authentication for this pattern, but no role mapping. <emphasis>OPTIONAL.</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </section>
+ </section>
+ </section>
+</chapter>
\ No newline at end of file
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 cc0a7c5..6165d76 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();
-
}
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index ba351f1..1bf8595 100755
--- a/pom.xml
+++ b/pom.xml
@@ -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>
proxy/launcher/pom.xml 43(+43 -0)
diff --git a/proxy/launcher/pom.xml b/proxy/launcher/pom.xml
new file mode 100755
index 0000000..d70d14d
--- /dev/null
+++ b/proxy/launcher/pom.xml
@@ -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>
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 0000000..56eab1e
--- /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 <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);
+ }
+}
proxy/pom.xml 31(+31 -0)
diff --git a/proxy/pom.xml b/proxy/pom.xml
new file mode 100755
index 0000000..b9d77ef
--- /dev/null
+++ b/proxy/pom.xml
@@ -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>
proxy/proxy-server/pom.xml 2(+0 -2)
diff --git a/proxy/proxy-server/pom.xml b/proxy/proxy-server/pom.xml
index 4b4d12a..ddc4a54 100755
--- a/proxy/proxy-server/pom.xml
+++ b/proxy/proxy-server/pom.xml
@@ -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>
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 9eb49db..2fd260b 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<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);
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 0000000..69dbbe0
--- /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 <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();
+
+ }
+}
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 3e03c3b..379656b 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);
}
diff --git a/testsuite/proxy/src/test/resources/proxy-config.json b/testsuite/proxy/src/test/resources/proxy-config.json
index f26d8e3..c6f583b 100755
--- a/testsuite/proxy/src/test/resources/proxy-config.json
+++ b/testsuite/proxy/src/test/resources/proxy-config.json
@@ -2,6 +2,9 @@
"bind-address": "localhost",
"http-port": "8080",
"https-port": "8443",
+ "keystore": "classpath:ssl.jks",
+ "keystore-password": "password",
+ "key-password": "password",
"target-url": "http://localhost:8082",
"applications": [
{
diff --git a/testsuite/proxy/src/test/resources/ssl.jks b/testsuite/proxy/src/test/resources/ssl.jks
new file mode 100755
index 0000000..341ff48
Binary files /dev/null and b/testsuite/proxy/src/test/resources/ssl.jks differ