keycloak-aplcache
Changes
integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java 14(+5 -9)
integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java 32(+0 -32)
integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java 93(+93 -0)
integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java 4(+2 -2)
integration/jetty/jetty9.1/pom.xml 14(+14 -0)
integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java 32(+0 -32)
integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java 94(+94 -0)
integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java 4(+2 -2)
integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java 32(+0 -32)
integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java 95(+95 -0)
integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java 13(+5 -8)
integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractJettySessionTokenStore.java 193(+99 -94)
integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java 15(+10 -5)
integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyCookieTokenStore.java 10(+10 -0)
integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyHttpFacade.java 8(+7 -1)
integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java 71(+4 -67)
integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java 10(+8 -2)
integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaCookieTokenStore.java 10(+10 -0)
integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaHttpFacade.java 8(+7 -1)
integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java 29(+2 -27)
integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java 25(+23 -2)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java 7(+1 -6)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java 8(+8 -0)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletSessionTokenStore.java 15(+15 -0)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowCookieTokenStore.java 10(+10 -0)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowSessionTokenStore.java 10(+10 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java 32(+32 -0)
testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml 29(+29 -0)
testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json 10(+10 -0)
testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml 29(+29 -0)
testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json 10(+10 -0)
testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml 29(+29 -0)
Details
diff --git a/core/src/main/java/org/keycloak/util/UriUtils.java b/core/src/main/java/org/keycloak/util/UriUtils.java
old mode 100644
new mode 100755
index 3f0f9af..70c6824
--- a/core/src/main/java/org/keycloak/util/UriUtils.java
+++ b/core/src/main/java/org/keycloak/util/UriUtils.java
@@ -1,6 +1,8 @@
package org.keycloak.util;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
+import java.net.URLDecoder;
import java.util.regex.Pattern;
/**
@@ -23,4 +25,42 @@ public class UriUtils {
return originPattern.matcher(url).matches();
}
+ public static MultivaluedHashMap<String, String> decodeQueryString(String queryString) {
+ MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+ if (queryString == null || queryString.equals("")) return map;
+
+ String[] params = queryString.split("&");
+
+ for (String param : params)
+ {
+ if (param.indexOf('=') >= 0)
+ {
+ String[] nv = param.split("=", 2);
+ try
+ {
+ String name = URLDecoder.decode(nv[0], "UTF-8");
+ String val = nv.length > 1 ? nv[1] : "";
+ map.add(name, URLDecoder.decode(val, "UTF-8"));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ else
+ {
+ try
+ {
+ String name = URLDecoder.decode(param, "UTF-8");
+ map.add(name, "");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return map;
+ }
+
}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterTokenStore.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterTokenStore.java
old mode 100644
new mode 100755
index 0d3be96..d07bffa
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterTokenStore.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterTokenStore.java
@@ -38,4 +38,7 @@ public interface AdapterTokenStore {
* @param securityContext context where refresh was performed
*/
void refreshCallback(RefreshableKeycloakSecurityContext securityContext);
+
+ void saveRequest();
+ boolean restoreRequest();
}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
index 312576e..48b5ed9 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
@@ -19,11 +19,12 @@ import java.util.concurrent.atomic.AtomicLong;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
-public abstract class OAuthRequestAuthenticator {
+public class OAuthRequestAuthenticator {
private static final Logger log = Logger.getLogger(OAuthRequestAuthenticator.class);
protected KeycloakDeployment deployment;
protected RequestAuthenticator reqAuthenticator;
protected int sslRedirectPort;
+ protected AdapterTokenStore tokenStore;
protected String tokenString;
protected String idTokenString;
protected IDToken idToken;
@@ -33,11 +34,12 @@ public abstract class OAuthRequestAuthenticator {
protected String refreshToken;
protected String strippedOauthParametersRequestUri;
- public OAuthRequestAuthenticator(RequestAuthenticator requestAuthenticator, HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort) {
+ public OAuthRequestAuthenticator(RequestAuthenticator requestAuthenticator, HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort, AdapterTokenStore tokenStore) {
this.reqAuthenticator = requestAuthenticator;
this.facade = facade;
this.deployment = deployment;
this.sslRedirectPort = sslRedirectPort;
+ this.tokenStore = tokenStore;
}
public AuthChallenge getChallenge() {
@@ -200,7 +202,7 @@ public abstract class OAuthRequestAuthenticator {
} else {
log.debug("redirecting to auth server");
challenge = loginRedirect();
- saveRequest();
+ tokenStore.saveRequest();
return AuthOutcome.NOT_ATTEMPTED;
}
} else {
@@ -214,12 +216,6 @@ public abstract class OAuthRequestAuthenticator {
}
- /**
- * Cache the request so that when we get redirected back, it gets invoked
- *
- */
- protected abstract void saveRequest();
-
protected AuthChallenge challenge(final int code) {
return new AuthChallenge() {
@Override
diff --git a/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java b/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java
new file mode 100755
index 0000000..e2dcfa5
--- /dev/null
+++ b/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java
@@ -0,0 +1,93 @@
+package org.keycloak.adapters.jetty;
+
+import org.eclipse.jetty.security.authentication.FormAuthenticator;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.MultiMap;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.util.MultivaluedHashMap;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JettySessionTokenStore extends AbstractJettySessionTokenStore {
+ public static final String CACHED_FORM_PARAMETERS = "__CACHED_FORM_PARAMETERS";
+ protected Request myRequest;
+
+ public JettySessionTokenStore(Request request, KeycloakDeployment deployment) {
+ super(request, deployment);
+ this.myRequest = request; // for IDE/compilation purposes
+ }
+
+ protected MultiMap<String> extractFormParameters(Request base_request) {
+ MultiMap<String> formParameters = new MultiMap<String>();
+ base_request.extractParameters();
+ return base_request.getParameters();
+ }
+ protected void restoreFormParameters(MultiMap<String> j_post, Request base_request) {
+ base_request.setParameters(j_post);
+ }
+
+ public boolean restoreRequest() {
+ HttpSession session = myRequest.getSession(false);
+ if (session == null) return false;
+ synchronized (session) {
+ String j_uri = (String) session.getAttribute(FormAuthenticator.__J_URI);
+ if (j_uri != null) {
+ // check if the request is for the same url as the original and restore
+ // params if it was a post
+ StringBuffer buf = myRequest.getRequestURL();
+ if (myRequest.getQueryString() != null)
+ buf.append("?").append(myRequest.getQueryString());
+ if (j_uri.equals(buf.toString())) {
+ String method = (String)session.getAttribute(__J_METHOD);
+ myRequest.setMethod(method);
+ MultivaluedHashMap<String, String> j_post = (MultivaluedHashMap<String, String>) session.getAttribute(CACHED_FORM_PARAMETERS);
+ if (j_post != null) {
+ MultiMap<String> map = new MultiMap<String>();
+ for (String key : j_post.keySet()) {
+ for (String val : j_post.getList(key)) {
+ map.add(key, val);
+ }
+ }
+ restoreFormParameters(map, myRequest);
+ }
+ session.removeAttribute(FormAuthenticator.__J_URI);
+ session.removeAttribute(__J_METHOD);
+ session.removeAttribute(FormAuthenticator.__J_POST);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void saveRequest() {
+ // remember the current URI
+ HttpSession session = myRequest.getSession();
+ synchronized (session) {
+ // But only if it is not set already, or we save every uri that leads to a login form redirect
+ if (session.getAttribute(FormAuthenticator.__J_URI) == null) {
+ StringBuffer buf = myRequest.getRequestURL();
+ if (myRequest.getQueryString() != null)
+ buf.append("?").append(myRequest.getQueryString());
+ session.setAttribute(FormAuthenticator.__J_URI, buf.toString());
+ session.setAttribute(__J_METHOD, myRequest.getMethod());
+
+ if ("application/x-www-form-urlencoded".equals(myRequest.getContentType()) && "POST".equalsIgnoreCase(myRequest.getMethod())) {
+ MultiMap<String> formParameters = extractFormParameters(myRequest);
+ MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+ for (String key : formParameters.keySet()) {
+ for (Object value : formParameters.getValues(key)) {
+ map.add(key, (String) value);
+ }
+ }
+ session.setAttribute(CACHED_FORM_PARAMETERS, map);
+ }
+ }
+ }
+ }
+
+}
diff --git a/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java b/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
index 06e1d99..d1ae6e0 100755
--- a/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
+++ b/integration/jetty/jetty8.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
@@ -21,8 +21,8 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
@Override
- protected AbstractJettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
- return new JettyRequestAuthenticator(deployment, this, tokenStore, facade, request);
+ public AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment) {
+ return new JettySessionTokenStore(request, resolvedDeployment);
}
@Override
integration/jetty/jetty9.1/pom.xml 14(+14 -0)
diff --git a/integration/jetty/jetty9.1/pom.xml b/integration/jetty/jetty9.1/pom.xml
index 0ce853b..6c23f5a 100755
--- a/integration/jetty/jetty9.1/pom.xml
+++ b/integration/jetty/jetty9.1/pom.xml
@@ -36,6 +36,20 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-jetty-core</artifactId>
<version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-security</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
diff --git a/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java b/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java
new file mode 100755
index 0000000..24fc9b2
--- /dev/null
+++ b/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java
@@ -0,0 +1,94 @@
+package org.keycloak.adapters.jetty;
+
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.security.authentication.FormAuthenticator;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.MultiMap;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.util.MultivaluedHashMap;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JettySessionTokenStore extends AbstractJettySessionTokenStore {
+ public static final String CACHED_FORM_PARAMETERS = "__CACHED_FORM_PARAMETERS";
+ protected Request myRequest;
+
+ public JettySessionTokenStore(Request request, KeycloakDeployment deployment) {
+ super(request, deployment);
+ this.myRequest = request; // for IDE/compilation purposes
+ }
+
+ protected MultiMap<String> extractFormParameters(Request base_request) {
+ MultiMap<String> formParameters = new MultiMap<String>();
+ base_request.extractParameters();
+ return base_request.getParameters();
+ }
+ protected void restoreFormParameters(MultiMap<String> j_post, Request base_request) {
+ base_request.setParameters(j_post);
+ }
+
+ public boolean restoreRequest() {
+ HttpSession session = myRequest.getSession(false);
+ if (session == null) return false;
+ synchronized (session) {
+ String j_uri = (String) session.getAttribute(FormAuthenticator.__J_URI);
+ if (j_uri != null) {
+ // check if the request is for the same url as the original and restore
+ // params if it was a post
+ StringBuffer buf = myRequest.getRequestURL();
+ if (myRequest.getQueryString() != null)
+ buf.append("?").append(myRequest.getQueryString());
+ if (j_uri.equals(buf.toString())) {
+ String method = (String)session.getAttribute(__J_METHOD);
+ myRequest.setMethod(HttpMethod.valueOf(method.toUpperCase()), method);
+ MultivaluedHashMap<String, String> j_post = (MultivaluedHashMap<String, String>) session.getAttribute(CACHED_FORM_PARAMETERS);
+ if (j_post != null) {
+ MultiMap<String> map = new MultiMap<String>();
+ for (String key : j_post.keySet()) {
+ for (String val : j_post.getList(key)) {
+ map.add(key, val);
+ }
+ }
+ restoreFormParameters(map, myRequest);
+ }
+ session.removeAttribute(FormAuthenticator.__J_URI);
+ session.removeAttribute(__J_METHOD);
+ session.removeAttribute(FormAuthenticator.__J_POST);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void saveRequest() {
+ // remember the current URI
+ HttpSession session = myRequest.getSession();
+ synchronized (session) {
+ // But only if it is not set already, or we save every uri that leads to a login form redirect
+ if (session.getAttribute(FormAuthenticator.__J_URI) == null) {
+ StringBuffer buf = myRequest.getRequestURL();
+ if (myRequest.getQueryString() != null)
+ buf.append("?").append(myRequest.getQueryString());
+ session.setAttribute(FormAuthenticator.__J_URI, buf.toString());
+ session.setAttribute(__J_METHOD, myRequest.getMethod());
+
+ if ("application/x-www-form-urlencoded".equals(myRequest.getContentType()) && "POST".equalsIgnoreCase(myRequest.getMethod())) {
+ MultiMap<String> formParameters = extractFormParameters(myRequest);
+ MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+ for (String key : formParameters.keySet()) {
+ for (Object value : formParameters.getValues(key)) {
+ map.add(key, (String) value);
+ }
+ }
+ session.setAttribute(CACHED_FORM_PARAMETERS, map);
+ }
+ }
+ }
+ }
+
+}
diff --git a/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java b/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
index 7ce92f8..db15f33 100755
--- a/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
+++ b/integration/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
@@ -21,8 +21,8 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
@Override
- protected AbstractJettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
- return new JettyRequestAuthenticator(deployment, this, tokenStore, facade, request);
+ public AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment) {
+ return new JettySessionTokenStore(request, resolvedDeployment);
}
@Override
diff --git a/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java b/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java
new file mode 100755
index 0000000..4ff9af9
--- /dev/null
+++ b/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/JettySessionTokenStore.java
@@ -0,0 +1,95 @@
+package org.keycloak.adapters.jetty;
+
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.security.authentication.FormAuthenticator;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.MultiMap;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.util.MultivaluedHashMap;
+
+import javax.servlet.http.HttpSession;
+import java.lang.reflect.Field;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JettySessionTokenStore extends AbstractJettySessionTokenStore {
+ public static final String CACHED_FORM_PARAMETERS = "__CACHED_FORM_PARAMETERS";
+ protected Request myRequest;
+
+ public JettySessionTokenStore(Request request, KeycloakDeployment deployment) {
+ super(request, deployment);
+ this.myRequest = request; // for IDE/compilation purposes
+ }
+
+ protected MultiMap<String> extractFormParameters(Request base_request) {
+ MultiMap<String> formParameters = new MultiMap<String>();
+ base_request.extractFormParameters(formParameters);
+ return formParameters;
+ }
+ protected void restoreFormParameters(MultiMap<String> j_post, Request base_request) {
+ base_request.setContentParameters(j_post);
+ }
+
+ public boolean restoreRequest() {
+ HttpSession session = myRequest.getSession(false);
+ if (session == null) return false;
+ synchronized (session) {
+ String j_uri = (String) session.getAttribute(FormAuthenticator.__J_URI);
+ if (j_uri != null) {
+ // check if the request is for the same url as the original and restore
+ // params if it was a post
+ StringBuffer buf = myRequest.getRequestURL();
+ if (myRequest.getQueryString() != null)
+ buf.append("?").append(myRequest.getQueryString());
+ if (j_uri.equals(buf.toString())) {
+ String method = (String)session.getAttribute(__J_METHOD);
+ myRequest.setMethod(HttpMethod.valueOf(method.toUpperCase()), method);
+ MultivaluedHashMap<String, String> j_post = (MultivaluedHashMap<String, String>) session.getAttribute(CACHED_FORM_PARAMETERS);
+ if (j_post != null) {
+ MultiMap<String> map = new MultiMap<String>();
+ for (String key : j_post.keySet()) {
+ for (String val : j_post.getList(key)) {
+ map.add(key, val);
+ }
+ }
+ restoreFormParameters(map, myRequest);
+ }
+ session.removeAttribute(FormAuthenticator.__J_URI);
+ session.removeAttribute(__J_METHOD);
+ session.removeAttribute(FormAuthenticator.__J_POST);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void saveRequest() {
+ // remember the current URI
+ HttpSession session = myRequest.getSession();
+ synchronized (session) {
+ // But only if it is not set already, or we save every uri that leads to a login form redirect
+ if (session.getAttribute(FormAuthenticator.__J_URI) == null) {
+ StringBuffer buf = myRequest.getRequestURL();
+ if (myRequest.getQueryString() != null)
+ buf.append("?").append(myRequest.getQueryString());
+ session.setAttribute(FormAuthenticator.__J_URI, buf.toString());
+ session.setAttribute(__J_METHOD, myRequest.getMethod());
+
+ if ("application/x-www-form-urlencoded".equals(myRequest.getContentType()) && "POST".equalsIgnoreCase(myRequest.getMethod())) {
+ MultiMap<String> formParameters = extractFormParameters(myRequest);
+ MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+ for (String key : formParameters.keySet()) {
+ for (Object value : formParameters.getValues(key)) {
+ map.add(key, (String) value);
+ }
+ }
+ session.setAttribute(CACHED_FORM_PARAMETERS, map);
+ }
+ }
+ }
+ }
+
+}
diff --git a/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java b/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
index d38e7d4..b43e27c 100755
--- a/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
+++ b/integration/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
@@ -20,12 +20,7 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
}
- @Override
- protected AbstractJettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
- return new JettyRequestAuthenticator(deployment, this, tokenStore, facade, request);
- }
-
- @Override
+ @Override
protected Request resolveRequest(ServletRequest req) {
return (req instanceof Request) ? (Request)req : HttpChannel.getCurrentHttpChannel().getRequest();
}
@@ -40,6 +35,8 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
};
}
-
-
+ @Override
+ public AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment) {
+ return new JettySessionTokenStore(request, resolvedDeployment);
+ }
}
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java
index 3d813e6..2e78eed 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java
@@ -65,14 +65,14 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
return new ByteArrayInputStream(json.getBytes());
}
- public static AdapterTokenStore getTokenStore(Request request, HttpFacade facade, KeycloakDeployment resolvedDeployment) {
+ public AdapterTokenStore getTokenStore(Request request, HttpFacade facade, KeycloakDeployment resolvedDeployment) {
AdapterTokenStore store = (AdapterTokenStore)request.getAttribute(TOKEN_STORE_NOTE);
if (store != null) {
return store;
}
if (resolvedDeployment.getTokenStore() == TokenStore.SESSION) {
- store = new JettySessionTokenStore(request, resolvedDeployment);
+ store = createSessionTokenStore(request, resolvedDeployment);
} else {
store = new JettyCookieTokenStore(request, facade, resolvedDeployment);
}
@@ -81,7 +81,9 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
return store;
}
- public static void logoutCurrent(Request request) {
+ public abstract AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment);
+
+ public void logoutCurrent(Request request) {
AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext)request.getAttribute(AdapterDeploymentContext.class.getName());
KeycloakSecurityContext ksc = (KeycloakSecurityContext)request.getAttribute(KeycloakSecurityContext.class.getName());
if (ksc != null) {
@@ -212,7 +214,7 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
nodesRegistrationManagement.tryRegister(deployment);
tokenStore.checkCurrentToken();
- AbstractJettyRequestAuthenticator authenticator = createRequestAuthenticator(request, facade, deployment, tokenStore);
+ JettyRequestAuthenticator authenticator = createRequestAuthenticator(request, facade, deployment, tokenStore);
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
if (facade.isEnded()) {
@@ -238,7 +240,10 @@ public abstract class AbstractKeycloakJettyAuthenticator extends LoginAuthentica
protected abstract Request resolveRequest(ServletRequest req);
- protected abstract AbstractJettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore);
+ protected JettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade,
+ KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
+ return new JettyRequestAuthenticator(facade, deployment, tokenStore, -1, request);
+ }
@Override
public String getAuthMethod() {
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyCookieTokenStore.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyCookieTokenStore.java
index c0b1685..3020f75 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyCookieTokenStore.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyCookieTokenStore.java
@@ -99,4 +99,14 @@ public class JettyCookieTokenStore implements AdapterTokenStore {
CookieTokenStore.removeCookie(facade);
return null;
}
+
+ @Override
+ public void saveRequest() {
+
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ return false;
+ }
}
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyHttpFacade.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyHttpFacade.java
index 75520ab..5a8c4c3 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyHttpFacade.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyHttpFacade.java
@@ -2,6 +2,8 @@ package org.keycloak.adapters.jetty;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.HttpFacade;
+import org.keycloak.util.MultivaluedHashMap;
+import org.keycloak.util.UriUtils;
import javax.security.cert.X509Certificate;
import javax.servlet.http.HttpServletResponse;
@@ -21,6 +23,7 @@ public class JettyHttpFacade implements HttpFacade {
protected HttpServletResponse response;
protected RequestFacade requestFacade = new RequestFacade();
protected ResponseFacade responseFacade = new ResponseFacade();
+ protected MultivaluedHashMap<String, String> queryParameters;
protected class RequestFacade implements Request {
@Override
@@ -39,7 +42,10 @@ public class JettyHttpFacade implements HttpFacade {
@Override
public String getQueryParamValue(String paramName) {
- return request.getParameter(paramName);
+ if (queryParameters == null) {
+ queryParameters = UriUtils.decodeQueryString(request.getQueryString());
+ }
+ return queryParameters.getFirst(paramName);
}
@Override
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 cb05e72..acf33a4 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
@@ -5,9 +5,12 @@ import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Manager;
+import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.authenticator.FormAuthenticator;
+import org.apache.catalina.authenticator.SavedRequest;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
+import org.apache.tomcat.util.buf.ByteChunk;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.adapters.AdapterDeploymentContext;
@@ -24,12 +27,15 @@ import org.keycloak.enums.TokenStore;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.keycloak.adapters.KeycloakConfigResolver;
@@ -180,7 +186,7 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat
nodesRegistrationManagement.tryRegister(deployment);
- CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, this, tokenStore, facade, request, createPrincipalFactory());
+ CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, tokenStore, facade, request, createPrincipalFactory());
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
if (facade.isEnded()) {
@@ -225,7 +231,7 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat
}
if (resolvedDeployment.getTokenStore() == TokenStore.SESSION) {
- store = new CatalinaSessionTokenStore(request, resolvedDeployment, userSessionManagement, createPrincipalFactory());
+ store = new CatalinaSessionTokenStore(request, resolvedDeployment, userSessionManagement, createPrincipalFactory(), this);
} else {
store = new CatalinaCookieTokenStore(request, facade, resolvedDeployment, createPrincipalFactory());
}
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 229efa3..b0b21ab 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
@@ -84,6 +84,16 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
CookieTokenStore.setTokenCookie(deployment, facade, secContext);
}
+ @Override
+ public void saveRequest() {
+
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ return false;
+ }
+
/**
* Verify if we already have authenticated and active principal in cookie. Perform refresh if it's not active
*
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 cf76d13..784a1fa 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,7 +2,9 @@ package org.keycloak.adapters.tomcat;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.HttpFacade;
+import org.keycloak.util.MultivaluedHashMap;
import org.keycloak.util.ServerCookie;
+import org.keycloak.util.UriUtils;
import javax.security.cert.X509Certificate;
import javax.servlet.http.HttpServletResponse;
@@ -22,6 +24,7 @@ public class CatalinaHttpFacade implements HttpFacade {
protected HttpServletResponse response;
protected RequestFacade requestFacade = new RequestFacade();
protected ResponseFacade responseFacade = new ResponseFacade();
+ protected MultivaluedHashMap<String, String> queryParameters;
protected class RequestFacade implements Request {
@Override
@@ -40,7 +43,10 @@ public class CatalinaHttpFacade implements HttpFacade {
@Override
public String getQueryParamValue(String paramName) {
- return request.getParameter(paramName);
+ if (queryParameters == null) {
+ queryParameters = UriUtils.decodeQueryString(request.getQueryString());
+ }
+ return queryParameters.getFirst(paramName);
}
@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 13d6835..58989ef 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
@@ -27,36 +27,22 @@ import javax.servlet.http.HttpSession;
*/
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,
+ AdapterTokenStore tokenStore,
CatalinaHttpFacade facade,
Request request,
GenericPrincipalFactory principalFactory) {
super(facade, deployment, tokenStore, request.getConnector().getRedirectPort());
- this.valve = valve;
this.request = request;
this.principalFactory = principalFactory;
}
@Override
protected OAuthRequestAuthenticator createOAuthAuthenticator() {
- return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort) {
- @Override
- protected void saveRequest() {
- try {
- // Support saving request just for TokenStore.SESSION TODO: Add to tokenStore spi?
- if (deployment.getTokenStore() == TokenStore.SESSION) {
- valve.keycloakSaveRequest(request);
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort, tokenStore);
}
@Override
@@ -99,17 +85,6 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator {
request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
}
- protected void restoreRequest() {
- if (request.getSessionInternal().getNote(Constants.FORM_REQUEST_NOTE) != null) {
- if (valve.keycloakRestoreRequest(request)) {
- log.finer("restoreRequest");
- } else {
- log.finer("Restore of original request failed");
- throw new RuntimeException("Restore of original request failed");
- }
- }
- }
-
@Override
protected String getHttpSessionId(boolean create) {
HttpSession session = request.getSession(create);
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 761a1d5..0e9cce1 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
@@ -1,5 +1,6 @@
package org.keycloak.adapters.tomcat;
+import java.io.IOException;
import java.util.Set;
import java.util.logging.Logger;
@@ -24,12 +25,18 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
private KeycloakDeployment deployment;
private CatalinaUserSessionManagement sessionManagement;
protected GenericPrincipalFactory principalFactory;
+ protected AbstractKeycloakAuthenticatorValve valve;
- public CatalinaSessionTokenStore(Request request, KeycloakDeployment deployment, CatalinaUserSessionManagement sessionManagement, GenericPrincipalFactory principalFactory) {
+
+ public CatalinaSessionTokenStore(Request request, KeycloakDeployment deployment,
+ CatalinaUserSessionManagement sessionManagement,
+ GenericPrincipalFactory principalFactory,
+ AbstractKeycloakAuthenticatorValve valve) {
this.request = request;
this.deployment = deployment;
this.sessionManagement = sessionManagement;
this.principalFactory = principalFactory;
+ this.valve = valve;
}
@Override
@@ -81,7 +88,7 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
request.setUserPrincipal(principal);
request.setAuthType("KEYCLOAK");
- ((CatalinaRequestAuthenticator)authenticator).restoreRequest();
+ restoreRequest();
return true;
}
@@ -112,4 +119,18 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) {
// no-op
}
+
+ @Override
+ public void saveRequest() {
+ try {
+ valve.keycloakSaveRequest(request);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ return valve.keycloakRestoreRequest(request);
+ }
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
index 5ef0734..f154ba3 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
@@ -53,12 +53,7 @@ public abstract class AbstractUndertowRequestAuthenticator extends RequestAuthen
@Override
protected OAuthRequestAuthenticator createOAuthAuthenticator() {
- return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort) {
- @Override
- protected void saveRequest() {
- // todo
- }
- };
+ return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort, tokenStore);
}
@Override
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java
new file mode 100755
index 0000000..3aae9c6
--- /dev/null
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java
@@ -0,0 +1,131 @@
+package org.keycloak.adapters.undertow;
+import io.undertow.UndertowLogger;
+import io.undertow.UndertowOptions;
+import io.undertow.server.Connectors;
+import io.undertow.server.HttpServerExchange;
+import io.undertow.server.session.Session;
+import io.undertow.servlet.handlers.ServletRequestContext;
+import io.undertow.servlet.spec.HttpSessionImpl;
+import io.undertow.util.HeaderMap;
+import io.undertow.util.HeaderValues;
+import io.undertow.util.Headers;
+import io.undertow.util.HttpString;
+import io.undertow.util.ImmediatePooled;
+
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.util.Iterator;
+
+/**
+ * Saved servlet request.
+ *
+ * Note bill burke: I had to fork this because Undertow was automatically restoring the request before the code could be processed and redirected.
+ *
+ * @author Stuart Douglas
+ */
+public class SavedRequest implements Serializable {
+
+ private static final String SESSION_KEY = SavedRequest.class.getName();
+
+ private final byte[] data;
+ private final int dataLength;
+ private final HttpString method;
+ private final String requestUri;
+ private final HeaderMap headerMap;
+
+ public SavedRequest(byte[] data, int dataLength, HttpString method, String requestUri, HeaderMap headerMap) {
+ this.data = data;
+ this.dataLength = dataLength;
+ this.method = method;
+ this.requestUri = requestUri;
+ this.headerMap = headerMap;
+ }
+
+ public static void trySaveRequest(final HttpServerExchange exchange) {
+ int maxSize = exchange.getConnection().getUndertowOptions().get(UndertowOptions.MAX_BUFFERED_REQUEST_SIZE, 16384);
+ if (maxSize > 0) {
+ //if this request has a body try and cache the response
+ if (!exchange.isRequestComplete()) {
+ final long requestContentLength = exchange.getRequestContentLength();
+ if (requestContentLength > maxSize) {
+ UndertowLogger.REQUEST_LOGGER.debugf("Request to %s was to large to save", exchange.getRequestURI());
+ return;//failed to save the request, we just return
+ }
+ //TODO: we should really be used pooled buffers
+ //TODO: we should probably limit the number of saved requests at any given time
+ byte[] buffer = new byte[maxSize];
+ int read = 0;
+ int res = 0;
+ InputStream in = exchange.getInputStream();
+ try {
+ while ((res = in.read(buffer, read, buffer.length - read)) > 0) {
+ read += res;
+ if (read == maxSize) {
+ UndertowLogger.REQUEST_LOGGER.debugf("Request to %s was to large to save", exchange.getRequestURI());
+ return;//failed to save the request, we just return
+ }
+ }
+ HeaderMap headers = new HeaderMap();
+ for(HeaderValues entry : exchange.getRequestHeaders()) {
+ if(entry.getHeaderName().equals(Headers.CONTENT_LENGTH) ||
+ entry.getHeaderName().equals(Headers.TRANSFER_ENCODING) ||
+ entry.getHeaderName().equals(Headers.CONNECTION)) {
+ continue;
+ }
+ headers.putAll(entry.getHeaderName(), entry);
+ }
+ SavedRequest request = new SavedRequest(buffer, read, exchange.getRequestMethod(), exchange.getRequestURI(), exchange.getRequestHeaders());
+ final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
+ HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
+ Session underlyingSession;
+ if(System.getSecurityManager() == null) {
+ underlyingSession = session.getSession();
+ } else {
+ underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
+ }
+ underlyingSession.setAttribute(SESSION_KEY, request);
+ } catch (IOException e) {
+ UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
+ }
+ }
+ }
+ }
+
+ public static void tryRestoreRequest(final HttpServerExchange exchange, HttpSession session) {
+ if(session instanceof HttpSessionImpl) {
+
+ Session underlyingSession;
+ if(System.getSecurityManager() == null) {
+ underlyingSession = ((HttpSessionImpl) session).getSession();
+ } else {
+ underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
+ }
+ SavedRequest request = (SavedRequest) underlyingSession.getAttribute(SESSION_KEY);
+ if(request != null) {
+ if(request.requestUri.equals(exchange.getRequestURI()) && exchange.isRequestComplete()) {
+ UndertowLogger.REQUEST_LOGGER.debugf("restoring request body for request to %s", request.requestUri);
+ exchange.setRequestMethod(request.method);
+ Connectors.ungetRequestBytes(exchange, new ImmediatePooled<ByteBuffer>(ByteBuffer.wrap(request.data, 0, request.dataLength)));
+ underlyingSession.removeAttribute(SESSION_KEY);
+ //clear the existing header map of everything except the connection header
+ //TODO: are there other headers we should preserve?
+ Iterator<HeaderValues> headerIterator = exchange.getRequestHeaders().iterator();
+ while (headerIterator.hasNext()) {
+ HeaderValues header = headerIterator.next();
+ if(!header.getHeaderName().equals(Headers.CONNECTION)) {
+ headerIterator.remove();
+ }
+ }
+ for(HeaderValues header : request.headerMap) {
+ exchange.getRequestHeaders().putAll(header.getHeaderName(), header);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java
index d28ff29..806fb9f 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java
@@ -19,12 +19,15 @@ package org.keycloak.adapters.undertow;
import io.undertow.security.api.SecurityContext;
import io.undertow.server.HttpServerExchange;
import io.undertow.servlet.handlers.ServletRequestContext;
+import io.undertow.servlet.util.SavedRequest;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.HttpFacade;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OAuthRequestAuthenticator;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
+import org.keycloak.enums.TokenStore;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -44,6 +47,11 @@ public class ServletRequestAuthenticator extends AbstractUndertowRequestAuthenti
}
@Override
+ protected OAuthRequestAuthenticator createOAuthAuthenticator() {
+ return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort, tokenStore);
+ }
+
+ @Override
protected void propagateKeycloakContext(KeycloakUndertowAccount account) {
super.propagateKeycloakContext(account);
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletSessionTokenStore.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletSessionTokenStore.java
index 2168d9d..74ebf1c 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletSessionTokenStore.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletSessionTokenStore.java
@@ -64,6 +64,7 @@ public class ServletSessionTokenStore implements AdapterTokenStore {
log.debug("Cached account found");
securityContext.authenticationComplete(account, "KEYCLOAK", false);
((AbstractUndertowRequestAuthenticator)authenticator).propagateKeycloakContext(account);
+ restoreRequest();
return true;
} else {
log.debug("Refresh failed. Account was not active. Returning null and invalidating Http session");
@@ -105,6 +106,20 @@ public class ServletSessionTokenStore implements AdapterTokenStore {
// no-op
}
+ @Override
+ public void saveRequest() {
+ SavedRequest.trySaveRequest(exchange);
+
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ HttpSession session = getSession(false);
+ if (session == null) return false;
+ SavedRequest.tryRestoreRequest(exchange, session);
+ return false;
+ }
+
protected HttpSession getSession(boolean create) {
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
HttpServletRequest req = (HttpServletRequest) servletRequestContext.getServletRequest();
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowCookieTokenStore.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowCookieTokenStore.java
index ccd695f..7dddb74 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowCookieTokenStore.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowCookieTokenStore.java
@@ -80,4 +80,14 @@ public class UndertowCookieTokenStore implements AdapterTokenStore {
public void refreshCallback(RefreshableKeycloakSecurityContext securityContext) {
CookieTokenStore.setTokenCookie(deployment, facade, securityContext);
}
+
+ @Override
+ public void saveRequest() {
+
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ return false;
+ }
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowSessionTokenStore.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowSessionTokenStore.java
index e5f013c..0dae4c9 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowSessionTokenStore.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowSessionTokenStore.java
@@ -71,6 +71,16 @@ public class UndertowSessionTokenStore implements AdapterTokenStore {
}
@Override
+ public void saveRequest() {
+
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ return false;
+ }
+
+ @Override
public void saveAccountInfo(KeycloakAccount account) {
Session session = Sessions.getOrCreateSession(exchange);
session.setAttribute(KeycloakUndertowAccount.class.getName(), account);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
index 6932a81..cef068a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
@@ -74,7 +74,6 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class AdapterTest {
- public static final String LOGIN_URL = OpenIDConnectService.loginPageUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build("demo").toString();
public static PublicKey realmPublicKey;
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@@ -99,6 +98,8 @@ public class AdapterTest {
System.setProperty("my.host.name", "localhost");
url = getClass().getResource("/adapter-test/session-keycloak.json");
deployApplication("session-portal", "/session-portal", SessionServlet.class, url.getPath(), "user");
+ url = getClass().getResource("/adapter-test/input-keycloak.json");
+ deployApplication("input-portal", "/input-portal", InputServlet.class, url.getPath(), "user", true, null, "/secured/*");
}
};
@@ -111,6 +112,11 @@ public class AdapterTest {
}
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+ @Test
public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout();
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index e32ff1f..d50fd71 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -87,6 +87,9 @@ public class AdapterTestStrategy extends ExternalResource {
@WebResource
protected LoginPage loginPage;
+ @WebResource
+ protected InputPage inputPage;
+
protected String LOGIN_URL = OpenIDConnectService.loginPageUrl(UriBuilder.fromUri(AUTH_SERVER_URL)).build("demo").toString();
public AdapterTestStrategy(String AUTH_SERVER_URL, String APP_SERVER_BASE_URL, AbstractKeycloakRule keycloakRule) {
@@ -133,6 +136,35 @@ public class AdapterTestStrategy extends ExternalResource {
}
@Test
+ public void testSavedPostRequest() throws Exception {
+ // test login to customer-portal which does a bearer request to customer-db
+ driver.navigate().to(APP_SERVER_BASE_URL + "/input-portal");
+ System.out.println("Current url: " + driver.getCurrentUrl());
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/input-portal" + slash);
+ inputPage.execute("hello");
+
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
+ loginPage.login("bburke@redhat.com", "password");
+ System.out.println("Current url: " + driver.getCurrentUrl());
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/input-portal/secured/post");
+ String pageSource = driver.getPageSource();
+ System.out.println(pageSource);
+ Assert.assertTrue(pageSource.contains("parameter=hello"));
+
+ // test logout
+
+ String logoutUri = OpenIDConnectService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL))
+ .queryParam(OAuth2Constants.REDIRECT_URI, APP_SERVER_BASE_URL + "/customer-portal").build("demo").toString();
+ driver.navigate().to(logoutUri);
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/product-portal");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
+ }
+
+
+ @Test
public void testLoginSSOAndLogout() throws Exception {
// test login to customer-portal which does a bearer request to customer-db
driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/InputPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/InputPage.java
new file mode 100755
index 0000000..bd09991
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/InputPage.java
@@ -0,0 +1,35 @@
+package org.keycloak.testsuite.adapter;
+
+import org.keycloak.testsuite.pages.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class InputPage extends AbstractPage {
+ @FindBy(id = "parameter")
+ private WebElement parameter;
+
+ @FindBy(name = "submit")
+ private WebElement submit;
+
+ public void execute(String param) {
+ parameter.clear();
+ parameter.sendKeys(param);
+
+ submit.click();
+ }
+
+
+ public boolean isCurrent() {
+ return driver.getTitle().equals("Input Page");
+ }
+
+ @Override
+ public void open() {
+ }
+
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/InputServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/InputServlet.java
new file mode 100755
index 0000000..db4c178
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/InputServlet.java
@@ -0,0 +1,42 @@
+package org.keycloak.testsuite.adapter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
+ */
+public class InputServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String appBase = System.getProperty("app.server.base.url", "http://localhost:8081");
+ String actionUrl = appBase + "/input-portal/secured/post";
+
+
+ resp.setContentType("text/html");
+ PrintWriter pw = resp.getWriter();
+ pw.printf("<html><head><title>%s</title></head><body>", "Input Page");
+ pw.printf("<form action=\"%s\" method=\"POST\">", actionUrl);
+ pw.println("<input id=\"parameter\" type=\"text\" name=\"parameter\">");
+ pw.println("<input name=\"submit\" type=\"submit\" value=\"Submit\"></form>");
+ pw.print("</body></html>");
+ pw.flush();
+
+
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.setContentType("text/plain");
+ PrintWriter pw = resp.getWriter();
+ pw.printf("parameter="+req.getParameter("parameter"));
+ pw.flush();
+ }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/SessionServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/SessionServlet.java
old mode 100644
new mode 100755
index c7c4d85..f9c5d0b
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/SessionServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/SessionServlet.java
@@ -1,38 +1,38 @@
-package org.keycloak.testsuite.adapter;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class SessionServlet extends HttpServlet {
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String counter = increaseAndGetCounter(req);
-
- resp.setContentType("text/html");
- PrintWriter pw = resp.getWriter();
- pw.printf("<html><head><title>%s</title></head><body>", "Session Test");
- pw.printf("Counter=%s", counter);
- pw.print("</body></html>");
- pw.flush();
-
-
- }
-
- private String increaseAndGetCounter(HttpServletRequest req) {
- HttpSession session = req.getSession();
- Integer counter = (Integer)session.getAttribute("counter");
- counter = (counter == null) ? 1 : counter + 1;
- session.setAttribute("counter", counter);
- return String.valueOf(counter);
- }
-}
+package org.keycloak.testsuite.adapter;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SessionServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String counter = increaseAndGetCounter(req);
+
+ resp.setContentType("text/html");
+ PrintWriter pw = resp.getWriter();
+ pw.printf("<html><head><title>%s</title></head><body>", "Session Test");
+ pw.printf("Counter=%s", counter);
+ pw.print("</body></html>");
+ pw.flush();
+
+
+ }
+
+ private String increaseAndGetCounter(HttpServletRequest req) {
+ HttpSession session = req.getSession();
+ Integer counter = (Integer)session.getAttribute("counter");
+ counter = (counter == null) ? 1 : counter + 1;
+ session.setAttribute("counter", counter);
+ return String.valueOf(counter);
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractPage.java
old mode 100644
new mode 100755
index c17b86a..4de2ca2
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractPage.java
@@ -39,8 +39,8 @@ public abstract class AbstractPage {
isCurrent());
}
- abstract boolean isCurrent();
+ abstract public boolean isCurrent();
- abstract void open() throws Exception;
+ abstract public void open() throws Exception;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/OAuthGrantPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/OAuthGrantPage.java
old mode 100644
new mode 100755
index 7fdbe06..baa1ae9
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/OAuthGrantPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/OAuthGrantPage.java
@@ -49,7 +49,7 @@ public class OAuthGrantPage extends AbstractPage {
}
@Override
- void open() {
+ public void open() {
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
index b89f2c3..d618567 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
@@ -150,6 +150,10 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
public void deployApplication(String name, String contextPath, Class<? extends Servlet> servletClass, String adapterConfigPath, String role, boolean isConstrained, Class<? extends KeycloakConfigResolver> keycloakConfigResolver) {
String constraintUrl = "/*";
+ deployApplication(name, contextPath, servletClass, adapterConfigPath, role, isConstrained, keycloakConfigResolver, constraintUrl);
+ }
+
+ public void deployApplication(String name, String contextPath, Class<? extends Servlet> servletClass, String adapterConfigPath, String role, boolean isConstrained, Class<? extends KeycloakConfigResolver> keycloakConfigResolver, String constraintUrl) {
DeploymentInfo di = createDeploymentInfo(name, contextPath, servletClass);
if (null == keycloakConfigResolver) {
di.addInitParameter("keycloak.config.file", adapterConfigPath);
diff --git a/testsuite/integration/src/test/resources/adapter-test/demorealm.json b/testsuite/integration/src/test/resources/adapter-test/demorealm.json
index 9a5da24..ec53bd7 100755
--- a/testsuite/integration/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/integration/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8081/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8081/input-portal",
+ "baseUrl": "http://localhost:8081/input-portal",
+ "redirectUris": [
+ "http://localhost:8081/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/integration/src/test/resources/adapter-test/input-keycloak.json b/testsuite/integration/src/test/resources/adapter-test/input-keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/integration/src/test/resources/adapter-test/input-keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty9Test.java
index 40da8ed..acf51ce 100755
--- a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty9Test.java
+++ b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty9Test.java
@@ -95,6 +95,7 @@ public class Jetty9Test {
list.add(new WebAppContext(new File(base, "customer-db").toString(), "/customer-db"));
list.add(new WebAppContext(new File(base, "product-portal").toString(), "/product-portal"));
list.add(new WebAppContext(new File(base, "session-portal").toString(), "/session-portal"));
+ list.add(new WebAppContext(new File(base, "input-portal").toString(), "/input-portal"));
list.add(new WebAppContext(new File(base, "secure-portal").toString(), "/secure-portal"));
@@ -118,6 +119,11 @@ public class Jetty9Test {
public AdapterTestStrategy testStrategy = new AdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8082", keycloakRule, true);
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+ @Test
public void testLoginSSOAndLogout() throws Exception {
testStrategy.testLoginSSOAndLogout();
}
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/demorealm.json b/testsuite/jetty/jetty81/src/test/resources/adapter-test/demorealm.json
index 9359cc9..ce40aec 100755
--- a/testsuite/jetty/jetty81/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8082/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8082/input-portal",
+ "baseUrl": "http://localhost:8082/input-portal",
+ "redirectUris": [
+ "http://localhost:8082/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml b/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml
new file mode 100755
index 0000000..1ec566d
--- /dev/null
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Get name="securityHandler">
+ <Set name="authenticator">
+ <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
+ <!--
+ <Set name="adapterConfig">
+ <New class="org.keycloak.representations.adapters.config.AdapterConfig">
+ <Set name="realm">tomcat</Set>
+ <Set name="resource">customer-portal</Set>
+ <Set name="authServerUrl">http://localhost:8081/auth</Set>
+ <Set name="sslRequired">external</Set>
+ <Set name="credentials">
+ <Map>
+ <Entry>
+ <Item>secret</Item>
+ <Item>password</Item>
+ </Entry>
+ </Map>
+ </Set>
+ <Set name="realmKey">MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB</Set>
+ </New>
+ </Set>
+ -->
+ </New>
+ </Set>
+ </Get>
+</Configure>
\ No newline at end of file
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
new file mode 100755
index 0000000..e4adb37
--- /dev/null
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <module-name>adapter-test</module-name>
+
+ <servlet>
+ <servlet-name>Servlet</servlet-name>
+ <servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Servlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Users</web-resource-name>
+ <url-pattern>/secured/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>user</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>user</role-name>
+ </security-role>
+</web-app>
diff --git a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java
index 528a2e0..19a8efd 100755
--- a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java
+++ b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java
@@ -95,6 +95,7 @@ public class Jetty9Test {
list.add(new WebAppContext(new File(base, "customer-db").toString(), "/customer-db"));
list.add(new WebAppContext(new File(base, "product-portal").toString(), "/product-portal"));
list.add(new WebAppContext(new File(base, "session-portal").toString(), "/session-portal"));
+ list.add(new WebAppContext(new File(base, "input-portal").toString(), "/input-portal"));
list.add(new WebAppContext(new File(base, "secure-portal").toString(), "/secure-portal"));
@@ -118,6 +119,11 @@ public class Jetty9Test {
public AdapterTestStrategy testStrategy = new AdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8082", keycloakRule, true);
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+ @Test
public void testLoginSSOAndLogout() throws Exception {
testStrategy.testLoginSSOAndLogout();
}
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/demorealm.json b/testsuite/jetty/jetty91/src/test/resources/adapter-test/demorealm.json
index 9359cc9..ce40aec 100755
--- a/testsuite/jetty/jetty91/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8082/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8082/input-portal",
+ "baseUrl": "http://localhost:8082/input-portal",
+ "redirectUris": [
+ "http://localhost:8082/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml b/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml
new file mode 100755
index 0000000..1ec566d
--- /dev/null
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Get name="securityHandler">
+ <Set name="authenticator">
+ <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
+ <!--
+ <Set name="adapterConfig">
+ <New class="org.keycloak.representations.adapters.config.AdapterConfig">
+ <Set name="realm">tomcat</Set>
+ <Set name="resource">customer-portal</Set>
+ <Set name="authServerUrl">http://localhost:8081/auth</Set>
+ <Set name="sslRequired">external</Set>
+ <Set name="credentials">
+ <Map>
+ <Entry>
+ <Item>secret</Item>
+ <Item>password</Item>
+ </Entry>
+ </Map>
+ </Set>
+ <Set name="realmKey">MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB</Set>
+ </New>
+ </Set>
+ -->
+ </New>
+ </Set>
+ </Get>
+</Configure>
\ No newline at end of file
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
new file mode 100755
index 0000000..e4adb37
--- /dev/null
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <module-name>adapter-test</module-name>
+
+ <servlet>
+ <servlet-name>Servlet</servlet-name>
+ <servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Servlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Users</web-resource-name>
+ <url-pattern>/secured/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>user</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>user</role-name>
+ </security-role>
+</web-app>
diff --git a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java
index 528a2e0..4d3c439 100755
--- a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java
+++ b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java
@@ -95,6 +95,7 @@ public class Jetty9Test {
list.add(new WebAppContext(new File(base, "customer-db").toString(), "/customer-db"));
list.add(new WebAppContext(new File(base, "product-portal").toString(), "/product-portal"));
list.add(new WebAppContext(new File(base, "session-portal").toString(), "/session-portal"));
+ list.add(new WebAppContext(new File(base, "input-portal").toString(), "/input-portal"));
list.add(new WebAppContext(new File(base, "secure-portal").toString(), "/secure-portal"));
@@ -123,6 +124,11 @@ public class Jetty9Test {
}
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+ @Test
public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout();
}
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/demorealm.json b/testsuite/jetty/jetty92/src/test/resources/adapter-test/demorealm.json
index 9359cc9..ce40aec 100755
--- a/testsuite/jetty/jetty92/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8082/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8082/input-portal",
+ "baseUrl": "http://localhost:8082/input-portal",
+ "redirectUris": [
+ "http://localhost:8082/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml b/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml
new file mode 100755
index 0000000..1ec566d
--- /dev/null
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/jetty-web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Get name="securityHandler">
+ <Set name="authenticator">
+ <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
+ <!--
+ <Set name="adapterConfig">
+ <New class="org.keycloak.representations.adapters.config.AdapterConfig">
+ <Set name="realm">tomcat</Set>
+ <Set name="resource">customer-portal</Set>
+ <Set name="authServerUrl">http://localhost:8081/auth</Set>
+ <Set name="sslRequired">external</Set>
+ <Set name="credentials">
+ <Map>
+ <Entry>
+ <Item>secret</Item>
+ <Item>password</Item>
+ </Entry>
+ </Map>
+ </Set>
+ <Set name="realmKey">MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB</Set>
+ </New>
+ </Set>
+ -->
+ </New>
+ </Set>
+ </Get>
+</Configure>
\ No newline at end of file
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
new file mode 100755
index 0000000..e4adb37
--- /dev/null
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <module-name>adapter-test</module-name>
+
+ <servlet>
+ <servlet-name>Servlet</servlet-name>
+ <servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Servlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Users</web-resource-name>
+ <url-pattern>/secured/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>user</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>user</role-name>
+ </security-role>
+</web-app>
diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
index 4f2a29e..d24a80d 100755
--- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
@@ -83,6 +83,7 @@ public class TomcatTest {
tomcat.deploy("/product-portal", "product-portal");
tomcat.deploy("/secure-portal", "secure-portal");
tomcat.deploy("/session-portal", "session-portal");
+ tomcat.deploy("/input-portal", "input-portal");
tomcat.start();
@@ -103,6 +104,11 @@ public class TomcatTest {
}
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+ @Test
public void testServletRequestLogout() throws Exception {
// can't test this. Servlet 2.5 doesn't have logout()
//testStrategy.testServletRequestLogout();
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/demorealm.json b/testsuite/tomcat6/src/test/resources/adapter-test/demorealm.json
index 9359cc9..ce40aec 100755
--- a/testsuite/tomcat6/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8082/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8082/input-portal",
+ "baseUrl": "http://localhost:8082/input-portal",
+ "redirectUris": [
+ "http://localhost:8082/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/META-INF/context.xml b/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/META-INF/context.xml
new file mode 100755
index 0000000..6f24639
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/META-INF/context.xml
@@ -0,0 +1,3 @@
+<Context path="/customer-portal">
+ <Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
+</Context>
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
new file mode 100755
index 0000000..e4adb37
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <module-name>adapter-test</module-name>
+
+ <servlet>
+ <servlet-name>Servlet</servlet-name>
+ <servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Servlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Users</web-resource-name>
+ <url-pattern>/secured/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>user</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>user</role-name>
+ </security-role>
+</web-app>
diff --git a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
index 70da95d..b79b085 100755
--- a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
+++ b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
@@ -87,6 +87,7 @@ public class Tomcat7Test {
tomcat.addWebapp("/product-portal", new File(base, "product-portal").toString());
tomcat.addWebapp("/secure-portal", new File(base, "secure-portal").toString());
tomcat.addWebapp("/session-portal", new File(base, "session-portal").toString());
+ tomcat.addWebapp("/input-portal", new File(base, "input-portal").toString());
tomcat.start();
//tomcat.getServer().await();
@@ -107,6 +108,12 @@ public class Tomcat7Test {
}
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+
+ @Test
public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout();
}
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/demorealm.json b/testsuite/tomcat7/src/test/resources/adapter-test/demorealm.json
index 9359cc9..ce40aec 100755
--- a/testsuite/tomcat7/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8082/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8082/input-portal",
+ "baseUrl": "http://localhost:8082/input-portal",
+ "redirectUris": [
+ "http://localhost:8082/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/META-INF/context.xml b/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/META-INF/context.xml
new file mode 100755
index 0000000..6f24639
--- /dev/null
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/META-INF/context.xml
@@ -0,0 +1,3 @@
+<Context path="/customer-portal">
+ <Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
+</Context>
\ No newline at end of file
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
new file mode 100755
index 0000000..e4adb37
--- /dev/null
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <module-name>adapter-test</module-name>
+
+ <servlet>
+ <servlet-name>Servlet</servlet-name>
+ <servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Servlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Users</web-resource-name>
+ <url-pattern>/secured/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>user</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>user</role-name>
+ </security-role>
+</web-app>
diff --git a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java
index 9ff92d8..e4834b6 100755
--- a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java
+++ b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java
@@ -87,6 +87,7 @@ public class TomcatTest {
tomcat.addWebapp("/product-portal", new File(base, "product-portal").toString());
tomcat.addWebapp("/secure-portal", new File(base, "secure-portal").toString());
tomcat.addWebapp("/session-portal", new File(base, "session-portal").toString());
+ tomcat.addWebapp("/input-portal", new File(base, "input-portal").toString());
tomcat.start();
//tomcat.getServer().await();
@@ -107,6 +108,13 @@ public class TomcatTest {
}
@Test
+ public void testSavedPostRequest() throws Exception {
+ testStrategy.testSavedPostRequest();
+ }
+
+
+
+ @Test
public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout();
}
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/demorealm.json b/testsuite/tomcat8/src/test/resources/adapter-test/demorealm.json
index 9359cc9..ce40aec 100755
--- a/testsuite/tomcat8/src/test/resources/adapter-test/demorealm.json
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/demorealm.json
@@ -125,6 +125,16 @@
"http://localhost:8082/session-portal/*"
],
"secret": "password"
+ },
+ {
+ "name": "input-portal",
+ "enabled": true,
+ "adminUrl": "http://localhost:8082/input-portal",
+ "baseUrl": "http://localhost:8082/input-portal",
+ "redirectUris": [
+ "http://localhost:8082/input-portal/*"
+ ],
+ "secret": "password"
}
],
"oauthClients": [
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/META-INF/context.xml b/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/META-INF/context.xml
new file mode 100755
index 0000000..6f24639
--- /dev/null
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/META-INF/context.xml
@@ -0,0 +1,3 @@
+<Context path="/customer-portal">
+ <Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
+</Context>
\ No newline at end of file
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
new file mode 100755
index 0000000..0b4b165
--- /dev/null
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json
@@ -0,0 +1,10 @@
+{
+ "realm" : "demo",
+ "resource" : "input-portal",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url" : "http://${my.host.name}:8081/auth",
+ "ssl-required" : "external",
+ "credentials" : {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
new file mode 100755
index 0000000..e4adb37
--- /dev/null
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <module-name>adapter-test</module-name>
+
+ <servlet>
+ <servlet-name>Servlet</servlet-name>
+ <servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Servlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Users</web-resource-name>
+ <url-pattern>/secured/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>user</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>user</role-name>
+ </security-role>
+</web-app>