diff --git a/distribution/adapters/as7-eap6-adapter/as7-modules/build.xml b/distribution/adapters/as7-eap6-adapter/as7-modules/build.xml
index e58f2b6a2f..cbf50eacfc 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-modules/build.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-modules/build.xml
@@ -52,6 +52,7 @@
+
diff --git a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
index 4e23733f18..21eeb8148a 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
@@ -25,6 +25,10 @@
org.keycloak
keycloak-adapter-spi
+
+ org.keycloak
+ keycloak-as7-adapter-spi
+
org.keycloak
keycloak-tomcat-adapter-spi
diff --git a/distribution/adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml b/distribution/adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
index f1ee530cda..645d8ece20 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
@@ -11,7 +11,6 @@
-
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
index 066a32a73f..70eeebb8e4 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterTokenStore.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterTokenStore.java
@@ -25,7 +25,7 @@ public interface AdapterTokenStore extends AdapterSessionStore {
*
* @param account
*/
- void saveAccountInfo(KeycloakAccount account);
+ void saveAccountInfo(OidcKeycloakAccount account);
/**
* Handle logout on store side and possibly propagate logout call to Keycloak
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/OidcKeycloakAccount.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/OidcKeycloakAccount.java
new file mode 100755
index 0000000000..fffc2427c1
--- /dev/null
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/OidcKeycloakAccount.java
@@ -0,0 +1,11 @@
+package org.keycloak.adapters;
+
+import org.keycloak.KeycloakSecurityContext;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public interface OidcKeycloakAccount extends KeycloakAccount {
+ KeycloakSecurityContext getKeycloakSecurityContext();
+}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java b/integration/adapter-spi/src/main/java/org/keycloak/adapters/KeycloakAccount.java
similarity index 73%
rename from integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java
rename to integration/adapter-spi/src/main/java/org/keycloak/adapters/KeycloakAccount.java
index a242779947..26299448ef 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java
+++ b/integration/adapter-spi/src/main/java/org/keycloak/adapters/KeycloakAccount.java
@@ -1,7 +1,5 @@
package org.keycloak.adapters;
-import org.keycloak.KeycloakSecurityContext;
-
import java.security.Principal;
import java.util.Set;
@@ -11,6 +9,6 @@ import java.util.Set;
*/
public interface KeycloakAccount {
Principal getPrincipal();
+
Set getRoles();
- KeycloakSecurityContext getKeycloakSecurityContext();
}
diff --git a/integration/as7-eap6/as7-adapter-spi/pom.xml b/integration/as7-eap6/as7-adapter-spi/pom.xml
new file mode 100755
index 0000000000..def1f56c23
--- /dev/null
+++ b/integration/as7-eap6/as7-adapter-spi/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.6.0.Final-SNAPSHOT
+ ../../../pom.xml
+
+ 4.0.0
+
+ keycloak-as7-adapter-spi
+ Keycloak AS7 SPI
+
+
+
+
+ org.keycloak
+ keycloak-adapter-spi
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ org.jboss.spec.javax.servlet
+ jboss-servlet-api_3.0_spec
+ provided
+
+
+ org.jboss.logging
+ jboss-logging
+ ${jboss.logging.version}
+ provided
+
+
+ org.jboss.web
+ jbossweb
+ 7.0.17.Final
+ provided
+
+
+ org.jboss.as
+ jboss-as-web
+ 7.1.2.Final
+ provided
+
+
+ org.keycloak
+ keycloak-tomcat-adapter-spi
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+
+
+ org.apache.tomcat
+ tomcat-catalina
+
+
+ org.apache.tomcat
+ catalina
+
+
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ ${maven.compiler.target}
+
+
+
+
+
+
diff --git a/integration/as7-eap6/as7-adapter/src/main/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactory.java b/integration/as7-eap6/as7-adapter-spi/src/main/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactory.java
similarity index 95%
rename from integration/as7-eap6/as7-adapter/src/main/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactory.java
rename to integration/as7-eap6/as7-adapter-spi/src/main/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactory.java
index 8bc50c92e9..b3925955c3 100755
--- a/integration/as7-eap6/as7-adapter/src/main/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactory.java
+++ b/integration/as7-eap6/as7-adapter-spi/src/main/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactory.java
@@ -9,7 +9,6 @@ import org.jboss.security.SecurityContext;
import org.jboss.security.SecurityContextAssociation;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
-import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
@@ -38,7 +37,7 @@ public class JBossWebPrincipalFactory extends GenericPrincipalFactory {
}
@Override
- public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set roleSet, final KeycloakSecurityContext securityContext) {
+ public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set roleSet) {
KeycloakAccount account = new KeycloakAccount() {
@Override
public Principal getPrincipal() {
@@ -49,11 +48,6 @@ public class JBossWebPrincipalFactory extends GenericPrincipalFactory {
public Set getRoles() {
return roleSet;
}
-
- @Override
- public KeycloakSecurityContext getKeycloakSecurityContext() {
- return securityContext;
- }
};
Subject subject = new Subject();
Set principals = subject.getPrincipals();
diff --git a/integration/as7-eap6/as7-adapter/src/test/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactoryTest.java b/integration/as7-eap6/as7-adapter-spi/src/test/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactoryTest.java
similarity index 100%
rename from integration/as7-eap6/as7-adapter/src/test/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactoryTest.java
rename to integration/as7-eap6/as7-adapter-spi/src/test/java/org/keycloak/adapters/jbossweb/JBossWebPrincipalFactoryTest.java
diff --git a/integration/as7-eap6/as7-adapter/pom.xml b/integration/as7-eap6/as7-adapter/pom.xml
index 9b938f4bf0..25a86a1f45 100755
--- a/integration/as7-eap6/as7-adapter/pom.xml
+++ b/integration/as7-eap6/as7-adapter/pom.xml
@@ -18,6 +18,10 @@
org.keycloak
keycloak-core
+
+ org.keycloak
+ keycloak-as7-adapter-spi
+
org.keycloak
keycloak-adapter-spi
diff --git a/integration/as7-eap6/pom.xml b/integration/as7-eap6/pom.xml
old mode 100644
new mode 100755
index 0080f469a1..ce7f8c8e78
--- a/integration/as7-eap6/pom.xml
+++ b/integration/as7-eap6/pom.xml
@@ -14,6 +14,7 @@
pom
+ as7-adapter-spi
as7-adapter
as7-subsystem
as7-server-subsystem
diff --git a/integration/jboss-adapter-core/pom.xml b/integration/jboss-adapter-core/pom.xml
index 50f0071e1c..427b534539 100755
--- a/integration/jboss-adapter-core/pom.xml
+++ b/integration/jboss-adapter-core/pom.xml
@@ -28,10 +28,6 @@
org.keycloak
keycloak-adapter-spi
-
- org.keycloak
- keycloak-adapter-core
-
org.apache.httpcomponents
httpclient
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyCookieTokenStore.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyCookieTokenStore.java
index 4c5b6ec435..cb7e0bc0d6 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyCookieTokenStore.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyCookieTokenStore.java
@@ -7,8 +7,8 @@ import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.CookieTokenStore;
import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -61,7 +61,7 @@ public class JettyCookieTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext)account.getKeycloakSecurityContext();
CookieTokenStore.setTokenCookie(deployment, facade, securityContext);
}
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java
index fbe20ba50b..1ab68b6afa 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java
@@ -7,9 +7,9 @@ import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.AdapterUtils;
import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OAuthRequestAuthenticator;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -41,7 +41,7 @@ public class JettyRequestAuthenticator extends RequestAuthenticator {
principal = skp;
final RefreshableKeycloakSecurityContext securityContext = skp.getKeycloakSecurityContext();
final Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
- KeycloakAccount account = new KeycloakAccount() {
+ OidcKeycloakAccount account = new OidcKeycloakAccount() {
@Override
public Principal getPrincipal() {
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettySessionTokenStore.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettySessionTokenStore.java
index f4c8b359b1..b007b06841 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettySessionTokenStore.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettySessionTokenStore.java
@@ -7,8 +7,8 @@ import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterSessionStore;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.AdapterUtils;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -77,7 +77,7 @@ public class JettySessionTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) account.getKeycloakSecurityContext();
request.getSession().setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
}
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java
old mode 100644
new mode 100755
index 338a72fd20..5d00165915
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/account/SimpleKeycloakAccount.java
@@ -1,6 +1,6 @@
package org.keycloak.adapters.springsecurity.account;
-import org.keycloak.adapters.KeycloakAccount;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import java.io.Serializable;
@@ -8,12 +8,12 @@ import java.security.Principal;
import java.util.Set;
/**
- * Concrete, serializable {@link KeycloakAccount} implementation.
+ * Concrete, serializable {@link org.keycloak.adapters.OidcKeycloakAccount} implementation.
*
* @author Scott Rossillo
* @version $Revision: 1 $
*/
-public class SimpleKeycloakAccount implements KeycloakAccount, Serializable {
+public class SimpleKeycloakAccount implements OidcKeycloakAccount, Serializable {
private Set roles;
private Principal principal;
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java
old mode 100644
new mode 100755
index b224ccfa70..a080acf004
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java
@@ -8,20 +8,18 @@ import org.keycloak.adapters.HttpFacade;
import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OAuthRequestAuthenticator;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
-import java.security.Principal;
import java.util.Set;
-import java.util.logging.Level;
/**
* Request authenticator adapter for Spring Security.
@@ -64,7 +62,7 @@ public class SpringSecurityRequestAuthenticator extends RequestAuthenticator {
final RefreshableKeycloakSecurityContext securityContext = principal.getKeycloakSecurityContext();
final Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
- final KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, securityContext);
+ final OidcKeycloakAccount account = new SimpleKeycloakAccount(principal, roles, securityContext);
request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
this.tokenStore.saveAccountInfo(account);
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java
old mode 100644
new mode 100755
index 0f67ed1800..6605a6bbec
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakPreAuthActionsFilter.java
@@ -70,7 +70,7 @@ public class KeycloakPreAuthActionsFilter extends GenericFilterBean implements A
HttpFacade facade = new SimpleHttpFacade((HttpServletRequest)request, (HttpServletResponse)response);
PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deploymentContext, facade);
if (handler.handleRequest()) {
- log.info("Pre-auth filter handled request: {}", ((HttpServletRequest) request).getRequestURI());
+ log.debug("Pre-auth filter handled request: {}", ((HttpServletRequest) request).getRequestURI());
} else {
chain.doFilter(request, response);
}
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java
old mode 100644
new mode 100755
index da4c1922ef..12fed2d3c9
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/KeycloakAuthenticationToken.java
@@ -1,6 +1,7 @@
package org.keycloak.adapters.springsecurity.token;
import org.keycloak.adapters.KeycloakAccount;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
@@ -51,7 +52,7 @@ public class KeycloakAuthenticationToken extends AbstractAuthenticationToken imp
return principal;
}
- public KeycloakAccount getAccount() {
- return (KeycloakAccount) this.getDetails();
+ public OidcKeycloakAccount getAccount() {
+ return (OidcKeycloakAccount) this.getDetails();
}
}
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java
old mode 100644
new mode 100755
index c16d73f107..abe8cfb999
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStore.java
@@ -2,8 +2,8 @@ package org.keycloak.adapters.springsecurity.token;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
import org.slf4j.Logger;
@@ -58,12 +58,12 @@ public class SpringSecurityTokenStore implements AdapterTokenStore {
return false;
}
- logger.info("Remote logged in already. Establishing state from security context.");
+ logger.debug("Remote logged in already. Establishing state from security context.");
token = (KeycloakAuthenticationToken) context.getAuthentication();
keycloakSecurityContext = token.getAccount().getKeycloakSecurityContext();
if (!deployment.getRealm().equals(keycloakSecurityContext.getRealm())) {
- logger.info("Account from security context is from a different realm than for the request.");
+ logger.debug("Account from security context is from a different realm than for the request.");
logout();
return false;
}
@@ -79,7 +79,7 @@ public class SpringSecurityTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java
old mode 100644
new mode 100755
index 6a035b5c78..cc751c4b76
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java
@@ -2,8 +2,8 @@ package org.keycloak.adapters.springsecurity.authentication;
import org.junit.Before;
import org.junit.Test;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
import org.keycloak.adapters.springsecurity.account.KeycloakRole;
@@ -38,7 +38,7 @@ public class KeycloakLogoutHandlerTest {
private AdapterDeploymentContextBean adapterDeploymentContextBean;
@Mock
- private KeycloakAccount keycloakAccount;
+ private OidcKeycloakAccount keycloakAccount;
@Mock
private KeycloakDeployment keycloakDeployment;
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java
old mode 100644
new mode 100755
index cdd305aaa4..301c344d8a
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java
@@ -6,9 +6,9 @@ import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OAuthRequestAuthenticator;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
@@ -82,7 +82,7 @@ public class SpringSecurityRequestAuthenticatorTest {
public void testCompleteOAuthAuthentication() throws Exception {
authenticator.completeOAuthAuthentication(principal);
verify(request).setAttribute(eq(KeycloakSecurityContext.class.getName()), eq(refreshableKeycloakSecurityContext));
- verify(tokenStore).saveAccountInfo(any(KeycloakAccount.class)); // FIXME: should verify account
+ verify(tokenStore).saveAccountInfo(any(OidcKeycloakAccount.class)); // FIXME: should verify account
}
@Test
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java
old mode 100644
new mode 100755
index e35efe622a..8796bf3eed
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/client/KeycloakClientRequestFactoryTest.java
@@ -4,7 +4,7 @@ import org.apache.http.client.methods.HttpUriRequest;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.adapters.KeycloakAccount;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.springsecurity.account.KeycloakRole;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.mockito.Mock;
@@ -28,7 +28,7 @@ public class KeycloakClientRequestFactoryTest {
private KeycloakClientRequestFactory factory;
@Mock
- private KeycloakAccount account;
+ private OidcKeycloakAccount account;
@Mock
private KeycloakAuthenticationToken keycloakAuthenticationToken;
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java
old mode 100644
new mode 100755
index b135906f7c..f1e29c5825
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticationProcessingFilterTest.java
@@ -6,6 +6,7 @@ import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
import org.keycloak.adapters.springsecurity.KeycloakAuthenticationException;
import org.keycloak.adapters.springsecurity.account.KeycloakRole;
@@ -67,7 +68,7 @@ public class KeycloakAuthenticationProcessingFilterTest {
private AuthenticationFailureHandler failureHandler;
@Mock
- private KeycloakAccount keycloakAccount;
+ private OidcKeycloakAccount keycloakAccount;
@Mock
private KeycloakDeployment keycloakDeployment;
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java
old mode 100644
new mode 100755
index 7088951d5e..b1624aac6f
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/token/SpringSecurityTokenStoreTest.java
@@ -3,8 +3,8 @@ package org.keycloak.adapters.springsecurity.token;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
import org.keycloak.adapters.springsecurity.account.KeycloakRole;
@@ -17,8 +17,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
-import javax.servlet.http.HttpSession;
-
import java.security.Principal;
import java.util.Collections;
@@ -66,7 +64,7 @@ public class SpringSecurityTokenStoreTest {
@Test
public void testSaveAccountInfo() throws Exception {
- KeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton("FOO"), keycloakSecurityContext);
+ OidcKeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton("FOO"), keycloakSecurityContext);
Authentication authentication;
store.saveAccountInfo(account);
@@ -78,7 +76,7 @@ public class SpringSecurityTokenStoreTest {
@Test(expected = IllegalStateException.class)
public void testSaveAccountInfoInvalidAuthenticationType() throws Exception {
- KeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton("FOO"), keycloakSecurityContext);
+ OidcKeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton("FOO"), keycloakSecurityContext);
Authentication authentication = new PreAuthenticatedAuthenticationToken("foo", "bar", Collections.singleton(new KeycloakRole("ROLE_FOO")));
SecurityContextHolder.getContext().setAuthentication(authentication);
store.saveAccountInfo(account);
diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java b/integration/tomcat/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java
similarity index 96%
rename from integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java
rename to integration/tomcat/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java
index 00190b5585..201a409d00 100755
--- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java
+++ b/integration/tomcat/tomcat-adapter-spi/src/main/java/org/keycloak/adapters/tomcat/GenericPrincipalFactory.java
@@ -2,7 +2,6 @@ package org.keycloak.adapters.tomcat;
import org.apache.catalina.Realm;
import org.apache.catalina.realm.GenericPrincipal;
-import org.keycloak.KeycloakSecurityContext;
import javax.security.auth.Subject;
import java.security.Principal;
@@ -20,7 +19,7 @@ import java.util.Set;
*/
public abstract class GenericPrincipalFactory {
- public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set roleSet, final KeycloakSecurityContext securityContext) {
+ public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set roleSet) {
Subject subject = new Subject();
Set principals = subject.getPrincipals();
principals.add(identity);
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 b0b21ab8f6..c70fa06c0e 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
@@ -11,8 +11,8 @@ import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.AdapterUtils;
import org.keycloak.adapters.CookieTokenStore;
import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -57,7 +57,7 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
securityContext.setCurrentRequestInfo(deployment, this);
Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
- GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), authenticatedPrincipal, roles, securityContext);
+ GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), authenticatedPrincipal, roles);
request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
request.setUserPrincipal(principal);
@@ -69,7 +69,7 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext)account.getKeycloakSecurityContext();
CookieTokenStore.setTokenCookie(deployment, facade, securityContext);
}
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 438f17015e..0883c762ef 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
@@ -1,19 +1,16 @@
package org.keycloak.adapters.tomcat;
-import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.connector.Request;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.AdapterUtils;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.OAuthRequestAuthenticator;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
-import org.keycloak.enums.TokenStore;
-import java.io.IOException;
import java.security.Principal;
import java.util.Set;
import java.util.logging.Level;
@@ -49,7 +46,7 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator {
protected void completeOAuthAuthentication(final KeycloakPrincipal skp) {
final RefreshableKeycloakSecurityContext securityContext = skp.getKeycloakSecurityContext();
final Set roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
- KeycloakAccount account = new KeycloakAccount() {
+ OidcKeycloakAccount account = new OidcKeycloakAccount() {
@Override
public Principal getPrincipal() {
@@ -79,7 +76,7 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator {
if (log.isLoggable(Level.FINE)) {
log.fine("Completing bearer authentication. Bearer roles: " + roles);
}
- Principal generalPrincipal = principalFactory.createPrincipal(request.getContext().getRealm(), principal, roles, securityContext);
+ Principal generalPrincipal = principalFactory.createPrincipal(request.getContext().getRealm(), principal, roles);
request.setUserPrincipal(generalPrincipal);
request.setAuthType(method);
request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaSessionTokenStore.java
index e0d3ca6fb4..9d147fa1df 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
@@ -5,12 +5,11 @@ import org.apache.catalina.connector.Request;
import org.apache.catalina.realm.GenericPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
-import java.io.IOException;
import java.io.Serializable;
import java.security.Principal;
import java.util.Set;
@@ -69,7 +68,7 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
}
protected void cleanSession(Session catalinaSession) {
- catalinaSession.getSession().removeAttribute(KeycloakAccount.class.getName());
+ catalinaSession.getSession().removeAttribute(OidcKeycloakAccount.class.getName());
catalinaSession.setPrincipal(null);
catalinaSession.setAuthType(null);
}
@@ -98,7 +97,7 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
GenericPrincipal principal = (GenericPrincipal) session.getPrincipal();
// in clustered environment in JBossWeb, principal is not serialized or saved
if (principal == null) {
- principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), account.getRoles(), securityContext);
+ principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), account.getRoles());
session.setPrincipal(principal);
session.setAuthType("KEYCLOAK");
@@ -110,7 +109,7 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
return true;
}
- public static class SerializableKeycloakAccount implements KeycloakAccount, Serializable {
+ public static class SerializableKeycloakAccount implements OidcKeycloakAccount, Serializable {
protected Set roles;
protected Principal principal;
protected RefreshableKeycloakSecurityContext securityContext;
@@ -138,10 +137,10 @@ public class CatalinaSessionTokenStore extends CatalinaAdapterSessionStore imple
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) account.getKeycloakSecurityContext();
Set roles = account.getRoles();
- GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), roles, securityContext);
+ GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), roles);
SerializableKeycloakAccount sAccount = new SerializableKeycloakAccount(roles, account.getPrincipal(), securityContext);
Session session = request.getSessionInternal(true);
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java
index ea9ab84cc2..c3a0184b26 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java
@@ -21,9 +21,8 @@ import org.jboss.logging.Logger;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.AdapterUtils;
-import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import java.io.Serializable;
@@ -34,7 +33,7 @@ import java.util.Set;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public class KeycloakUndertowAccount implements Account, Serializable, KeycloakAccount {
+public class KeycloakUndertowAccount implements Account, Serializable, OidcKeycloakAccount {
protected static Logger log = Logger.getLogger(KeycloakUndertowAccount.class);
protected KeycloakPrincipal principal;
protected Set accountRoles;
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 74ebf1cd20..5996589748 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
@@ -9,8 +9,8 @@ import io.undertow.servlet.handlers.ServletRequestContext;
import org.jboss.logging.Logger;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.AdapterTokenStore;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -75,7 +75,7 @@ public class ServletSessionTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
HttpSession session = getSession(true);
session.setAttribute(KeycloakUndertowAccount.class.getName(), account);
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 7dddb74762..4be2bbeca9 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
@@ -6,8 +6,8 @@ import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.AdapterTokenStore;
import org.keycloak.adapters.CookieTokenStore;
import org.keycloak.adapters.HttpFacade;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -63,7 +63,7 @@ public class UndertowCookieTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
RefreshableKeycloakSecurityContext secContext = (RefreshableKeycloakSecurityContext)account.getKeycloakSecurityContext();
CookieTokenStore.setTokenCookie(deployment, facade, secContext);
}
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 0dae4c9a43..f9fa6c0ce8 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
@@ -6,8 +6,8 @@ import io.undertow.server.session.Session;
import io.undertow.util.Sessions;
import org.jboss.logging.Logger;
import org.keycloak.adapters.AdapterTokenStore;
-import org.keycloak.adapters.KeycloakAccount;
import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.OidcKeycloakAccount;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.RequestAuthenticator;
@@ -81,7 +81,7 @@ public class UndertowSessionTokenStore implements AdapterTokenStore {
}
@Override
- public void saveAccountInfo(KeycloakAccount account) {
+ public void saveAccountInfo(OidcKeycloakAccount account) {
Session session = Sessions.getOrCreateSession(exchange);
session.setAttribute(KeycloakUndertowAccount.class.getName(), account);
sessionManagement.login(session.getSessionManager());
diff --git a/pom.xml b/pom.xml
index 36e8e3e0b1..4fc5896d65 100755
--- a/pom.xml
+++ b/pom.xml
@@ -768,6 +768,11 @@
keycloak-as7-adapter
${project.version}
+
+ org.keycloak
+ keycloak-as7-adapter-spi
+ ${project.version}
+
org.keycloak
keycloak-installed-adapter
@@ -873,6 +878,11 @@
keycloak-tomcat6-adapter
${project.version}
+
+ org.keycloak
+ keycloak-tomcat6-saml-adapter
+ ${project.version}
+
org.keycloak
keycloak-tomcat7-adapter
@@ -973,6 +983,11 @@
keycloak-saml-adapter-core
${project.version}
+
+ org.keycloak
+ keycloak-tomcat-core-saml-adapter
+ ${project.version}
+
org.keycloak
keycloak-undertow-saml-adapter
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java
index 1cef2b160a..bcba3d05ff 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java
@@ -28,7 +28,7 @@ public class InitiateLogin implements AuthChallenge {
@Override
public boolean errorPage() {
- return true;
+ return false;
}
@Override
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
index ade3e47dcc..f95bb5d650 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
@@ -104,14 +104,9 @@ public abstract class SamlAuthenticator {
try {
SamlUtil.sendSaml(true, facade, deployment.getIDP().getSingleLogoutService().getRequestBindingUrl(), binding, logoutBuilder.buildDocument(), deployment.getIDP().getSingleLogoutService().getRequestBinding());
- } catch (ProcessingException e) {
- throw new RuntimeException(e);
- } catch (ConfigurationException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- throw new RuntimeException(e);
- } catch (ParsingException e) {
- throw new RuntimeException(e);
+ } catch (Exception e) {
+ log.error("Could not send global logout SAML request", e);
+ return AuthOutcome.FAILED;
}
return AuthOutcome.NOT_ATTEMPTED;
}
@@ -134,18 +129,24 @@ public abstract class SamlAuthenticator {
RequestAbstractType requestAbstractType = (RequestAbstractType) holder.getSamlObject();
if (!requestUri.equals(requestAbstractType.getDestination().toString())) {
log.error("expected destination '" + requestUri + "' got '" + requestAbstractType.getDestination() + "'");
- throw new RuntimeException("destination not equal to request.");
+ return AuthOutcome.FAILED;
}
if (requestAbstractType instanceof LogoutRequestType) {
if (deployment.getIDP().getSingleLogoutService().validateRequestSignature()) {
- validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY);
+ try {
+ validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY);
+ } catch (VerificationException e) {
+ log.error("Failed to verify saml request signature", e);
+ return AuthOutcome.FAILED;
+ }
}
LogoutRequestType logout = (LogoutRequestType) requestAbstractType;
return logoutRequest(logout, relayState);
} else {
- throw new RuntimeException("unknown SAML request type");
+ log.error("unknown SAML request type");
+ return AuthOutcome.FAILED;
}
}
@@ -173,12 +174,9 @@ public abstract class SamlAuthenticator {
try {
SamlUtil.sendSaml(false, facade, deployment.getIDP().getSingleLogoutService().getResponseBindingUrl(), binding, builder.buildDocument(),
deployment.getIDP().getSingleLogoutService().getResponseBinding());
- } catch (ConfigurationException e) {
- throw new RuntimeException(e);
- } catch (ProcessingException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ } catch (Exception e) {
+ log.error("Could not send logout response SAML request", e);
+ return AuthOutcome.FAILED;
}
return AuthOutcome.NOT_ATTEMPTED;
@@ -202,17 +200,28 @@ public abstract class SamlAuthenticator {
StatusResponseType statusResponse = (StatusResponseType)holder.getSamlObject();
// validate destination
if (!requestUri.equals(statusResponse.getDestination())) {
- throw new RuntimeException("destination not equal to request");
+ log.error("Request URI does not match SAML request destination");
+ return AuthOutcome.FAILED;
}
if (statusResponse instanceof ResponseType) {
if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) {
- validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+ try {
+ validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+ } catch (VerificationException e) {
+ log.error("Failed to verify saml response signature", e);
+ return AuthOutcome.FAILED;
+ }
}
return handleLoginResponse((ResponseType)statusResponse);
} else {
if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) {
- validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+ try {
+ validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+ } catch (VerificationException e) {
+ log.error("Failed to verify saml response signature", e);
+ return AuthOutcome.FAILED;
+ }
}
// todo need to check that it is actually a LogoutResponse
return handleLogoutResponse(holder, statusResponse, relayState);
@@ -220,16 +229,11 @@ public abstract class SamlAuthenticator {
}
- private void validateSamlSignature(SAMLDocumentHolder holder, boolean postBinding, String paramKey) {
- try {
- if (postBinding) {
- verifyPostBindingSignature(holder.getSamlDocument(), deployment.getIDP().getSignatureValidationKey());
- } else {
- verifyRedirectBindingSignature(deployment.getIDP().getSignatureValidationKey(), paramKey);
- }
- } catch (VerificationException e) {
- log.error("validation failed", e);
- throw new RuntimeException("invalid document signature");
+ private void validateSamlSignature(SAMLDocumentHolder holder, boolean postBinding, String paramKey) throws VerificationException {
+ if (postBinding) {
+ verifyPostBindingSignature(holder.getSamlDocument(), deployment.getIDP().getSignatureValidationKey());
+ } else {
+ verifyRedirectBindingSignature(deployment.getIDP().getSignatureValidationKey(), paramKey);
}
}
@@ -240,12 +244,9 @@ public abstract class SamlAuthenticator {
if (AssertionUtil.hasExpired(assertion)) {
return initiateLogin();
}
- } catch (ParsingException e) {
- throw new RuntimeException(e);
- } catch (ProcessingException e) {
- throw new RuntimeException(e);
- } catch (ConfigurationException e) {
- throw new RuntimeException(e);
+ } catch (Exception e) {
+ log.error("Error extracting SAML assertion, e");
+ return AuthOutcome.FAILED;
}
SubjectType subject = assertion.getSubject();
@@ -269,6 +270,7 @@ public abstract class SamlAuthenticator {
if (attributeValues != null) {
for (Object attrValue : attributeValues) {
String role = getAttributeValue(attrValue);
+ log.info("Add role: " + role);
roles.add(role);
}
}
@@ -314,22 +316,7 @@ public abstract class SamlAuthenticator {
final SamlPrincipal principal = new SamlPrincipal(principalName, principalName, subjectNameID.getFormat().toString(), attributes, friendlyAttributes);
String index = authn == null ? null : authn.getSessionIndex();
final String sessionIndex = index;
- SamlSession account = new SamlSession() {
- @Override
- public SamlPrincipal getPrincipal() {
- return principal;
- }
-
- @Override
- public Set getRoles() {
- return roles;
- }
-
- @Override
- public String getSessionIndex() {
- return sessionIndex;
- }
- };
+ SamlSession account = new SamlSession(principal, roles, sessionIndex);
sessionStore.saveAccount(account);
completeAuthentication(account);
@@ -343,7 +330,7 @@ public abstract class SamlAuthenticator {
} else {
log.debug("IDP initiated invocation");
}
-
+ log.debug("AUTHENTICATED authn");
return AuthOutcome.AUTHENTICATED;
}
@@ -351,7 +338,7 @@ public abstract class SamlAuthenticator {
protected abstract void completeAuthentication(SamlSession account);
private String getAttributeValue(Object attrValue) {
- String value;
+ String value = null;
if (attrValue instanceof String) {
value = (String)attrValue;
} else if (attrValue instanceof Node) {
@@ -360,8 +347,9 @@ public abstract class SamlAuthenticator {
} else if (attrValue instanceof NameIDType) {
NameIDType nameIdType = (NameIDType) attrValue;
value = nameIdType.getValue();
- } else
- throw new RuntimeException("Unknown attribute value type: " + attrValue.getClass().getName());
+ } else {
+ log.warn("Unable to extract unknown SAML assertion attribute value type: " + attrValue.getClass().getName());
+ }
return value;
}
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSession.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSession.java
index b3a1833efa..df53ed6a6a 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSession.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlSession.java
@@ -8,8 +8,29 @@ import java.util.Set;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public interface SamlSession extends Serializable {
- SamlPrincipal getPrincipal();
- Set getRoles();
- String getSessionIndex();
+public class SamlSession implements Serializable {
+ private SamlPrincipal principal;
+ private Set roles;
+ private String sessionIndex;
+
+ public SamlSession() {
+ }
+
+ public SamlSession(SamlPrincipal principal, Set roles, String sessionIndex) {
+ this.principal = principal;
+ this.roles = roles;
+ this.sessionIndex = sessionIndex;
+ }
+
+ public SamlPrincipal getPrincipal() {
+ return principal;
+ }
+
+ public Set getRoles() {
+ return roles;
+ }
+
+ public String getSessionIndex() {
+ return sessionIndex;
+ }
}
diff --git a/saml/client-adapter/pom.xml b/saml/client-adapter/pom.xml
index e1c0b715a6..9c2ac047a9 100755
--- a/saml/client-adapter/pom.xml
+++ b/saml/client-adapter/pom.xml
@@ -16,5 +16,6 @@
core
undertow
+ tomcat
diff --git a/saml/client-adapter/tomcat/pom.xml b/saml/client-adapter/tomcat/pom.xml
new file mode 100755
index 0000000000..141343cd3b
--- /dev/null
+++ b/saml/client-adapter/tomcat/pom.xml
@@ -0,0 +1,22 @@
+
+
+ keycloak-parent
+ org.keycloak
+ 1.6.0.Final-SNAPSHOT
+ ../../../pom.xml
+
+ Keycloak SAML Tomcat Integration
+
+ 4.0.0
+
+ keycloak-tomcat-saml-integration-pom
+ pom
+
+
+ tomcat-core
+ tomcat6
+ tomcat7
+ tomcat8
+
+
diff --git a/saml/client-adapter/tomcat/tomcat-core/pom.xml b/saml/client-adapter/tomcat/tomcat-core/pom.xml
new file mode 100755
index 0000000000..5402eacdf9
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat-core/pom.xml
@@ -0,0 +1,89 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.6.0.Final-SNAPSHOT
+ ../../../../pom.xml
+
+ 4.0.0
+
+ keycloak-tomcat-core-saml-adapter
+ Keycloak Tomcat Core SAML Integration
+
+
+
+ 6.0.41
+
+
+
+
+
+ org.jboss.logging
+ jboss-logging
+ ${jboss.logging.version}
+
+
+ org.keycloak
+ keycloak-core
+
+
+ org.keycloak
+ keycloak-adapter-spi
+
+
+ org.keycloak
+ keycloak-tomcat-adapter-spi
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+
+
+ org.keycloak
+ keycloak-saml-core
+
+
+ org.keycloak
+ keycloak-saml-adapter-core
+
+
+
+ org.apache.tomcat
+ catalina
+ ${tomcat.version}
+ compile
+
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+
+
+
diff --git a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
new file mode 100755
index 0000000000..bf21055c22
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
@@ -0,0 +1,255 @@
+package org.keycloak.adapters.saml;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.authenticator.FormAuthenticator;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.adapters.AuthChallenge;
+import org.keycloak.adapters.AuthOutcome;
+import org.keycloak.adapters.HttpFacade;
+import org.keycloak.adapters.InMemorySessionIdMapper;
+import org.keycloak.adapters.SessionIdMapper;
+import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
+import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
+import org.keycloak.adapters.tomcat.CatalinaHttpFacade;
+import org.keycloak.adapters.tomcat.CatalinaUserSessionManagement;
+import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+import org.keycloak.constants.AdapterConstants;
+import org.keycloak.saml.common.exceptions.ParsingException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+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.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Keycloak authentication valve
+ *
+ * @author Davide Ungari
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator implements LifecycleListener {
+
+ public static final String TOKEN_STORE_NOTE = "TOKEN_STORE_NOTE";
+
+ private final static Logger log = Logger.getLogger(""+AbstractSamlAuthenticatorValve.class);
+ protected CatalinaUserSessionManagement userSessionManagement = new CatalinaUserSessionManagement();
+ protected SamlDeploymentContext deploymentContext;
+ protected SessionIdMapper mapper = new InMemorySessionIdMapper();
+
+ @Override
+ public void lifecycleEvent(LifecycleEvent event) {
+ if (Lifecycle.START_EVENT.equals(event.getType())) {
+ cache = false;
+ } else if (Lifecycle.AFTER_START_EVENT.equals(event.getType())) {
+ keycloakInit();
+ } else if (event.getType() == Lifecycle.BEFORE_STOP_EVENT) {
+ beforeStop();
+ }
+ }
+
+ protected void logoutInternal(Request request) {
+ KeycloakSecurityContext ksc = (KeycloakSecurityContext)request.getAttribute(KeycloakSecurityContext.class.getName());
+ if (ksc != null) {
+ CatalinaHttpFacade facade = new CatalinaHttpFacade(null, request);
+ SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
+ SamlSessionStore tokenStore = getTokenStore(request, facade, deployment);
+ tokenStore.logoutAccount();
+ }
+ request.setUserPrincipal(null);
+ }
+
+ @SuppressWarnings("UseSpecificCatch")
+ public void keycloakInit() {
+ // Possible scenarios:
+ // 1) The deployment has a keycloak.config.resolver specified and it exists:
+ // Outcome: adapter uses the resolver
+ // 2) The deployment has a keycloak.config.resolver and isn't valid (doesn't exists, isn't a resolver, ...) :
+ // Outcome: adapter is left unconfigured
+ // 3) The deployment doesn't have a keycloak.config.resolver , but has a keycloak.json (or equivalent)
+ // Outcome: adapter uses it
+ // 4) The deployment doesn't have a keycloak.config.resolver nor keycloak.json (or equivalent)
+ // Outcome: adapter is left unconfigured
+
+ String configResolverClass = context.getServletContext().getInitParameter("keycloak.config.resolver");
+ if (configResolverClass != null) {
+ try {
+ throw new RuntimeException("Not implemented yet");
+ //KeycloakConfigResolver configResolver = (KeycloakConfigResolver) context.getLoader().getClassLoader().loadClass(configResolverClass).newInstance();
+ //deploymentContext = new SamlDeploymentContext(configResolver);
+ //log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass);
+ } catch (Exception ex) {
+ log.log(Level.FINE, "The specified resolver {0} could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: {1}", new Object[]{configResolverClass, ex.getMessage()});
+ //deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment());
+ }
+ } else {
+ InputStream is = getConfigInputStream(context);
+ final SamlDeployment deployment;
+ if (is == null) {
+ log.info("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
+ deployment = new DefaultSamlDeployment();
+ } else {
+ try {
+ ResourceLoader loader = new ResourceLoader() {
+ @Override
+ public InputStream getResourceAsStream(String resource) {
+ return context.getServletContext().getResourceAsStream(resource);
+ }
+ };
+ deployment = new DeploymentBuilder().build(is, loader);
+ } catch (ParsingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ deploymentContext = new SamlDeploymentContext(deployment);
+ log.fine("Keycloak is using a per-deployment configuration.");
+ }
+
+ context.getServletContext().setAttribute(SamlDeploymentContext.class.getName(), deploymentContext);
+ }
+
+ protected void beforeStop() {
+ }
+
+ private static InputStream getConfigFromServletContext(ServletContext servletContext) {
+ String xml = servletContext.getInitParameter(AdapterConstants.AUTH_DATA_PARAM_NAME);
+ if (xml == null) {
+ return null;
+ }
+ log.finest("**** using " + AdapterConstants.AUTH_DATA_PARAM_NAME);
+ log.finest(xml);
+ return new ByteArrayInputStream(xml.getBytes());
+ }
+
+ private static InputStream getConfigInputStream(Context context) {
+ InputStream is = getConfigFromServletContext(context.getServletContext());
+ if (is == null) {
+ String path = context.getServletContext().getInitParameter("keycloak.config.file");
+ if (path == null) {
+ log.fine("**** using /WEB-INF/keycloak-saml.xml");
+ is = context.getServletContext().getResourceAsStream("/WEB-INF/keycloak-saml.xml");
+ } else {
+ try {
+ is = new FileInputStream(path);
+ } catch (FileNotFoundException e) {
+ log.log(Level.SEVERE, "NOT FOUND {0}", path);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return is;
+ }
+
+ @Override
+ public void invoke(Request request, Response response) throws IOException, ServletException {
+ log.fine("*********************** SAML ************");
+ try {
+ super.invoke(request, response);
+ } finally {
+ }
+ }
+
+ protected abstract GenericPrincipalFactory createPrincipalFactory();
+ protected abstract boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException;
+ protected void forwardToLogoutPage(Request request, HttpServletResponse response,SamlDeployment deployment) {
+ RequestDispatcher disp = request.getRequestDispatcher(deployment.getLogoutPage());
+ //make sure the login page is never cached
+ response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+ response.setHeader("Pragma", "no-cache");
+ response.setHeader("Expires", "0");
+
+
+ try {
+ disp.forward(request, response);
+ } catch (ServletException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ protected boolean authenticateInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
+ log.info("authenticateInternal");
+ CatalinaHttpFacade facade = new CatalinaHttpFacade(response, request);
+ SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
+ if (deployment == null || !deployment.isConfigured()) {
+ log.fine("deployment not configured");
+ return false;
+ }
+ SamlSessionStore tokenStore = getTokenStore(request, facade, deployment);
+
+
+ CatalinaSamlAuthenticator authenticator = new CatalinaSamlAuthenticator(facade, deployment, tokenStore);
+ AuthOutcome outcome = authenticator.authenticate();
+ if (outcome == AuthOutcome.AUTHENTICATED) {
+ log.fine("AUTHENTICATED");
+ if (facade.isEnded()) {
+ return false;
+ }
+ return true;
+ }
+ if (outcome == AuthOutcome.LOGGED_OUT) {
+ logoutInternal(request);
+ if (deployment.getLogoutPage() != null) {
+ forwardToLogoutPage(request, response, deployment);
+
+ }
+ log.fine("Logging OUT");
+ return false;
+ }
+
+ AuthChallenge challenge = authenticator.getChallenge();
+ if (challenge != null) {
+ log.fine("challenge");
+ if (loginConfig == null) {
+ loginConfig = request.getContext().getLoginConfig();
+ }
+ if (challenge.errorPage()) {
+ log.fine("error page");
+ if (forwardToErrorPageInternal(request, response, loginConfig))return false;
+ }
+ log.fine("sending challenge");
+ challenge.challenge(facade);
+ }
+ log.fine("No challenge, but failed authentication");
+ return false;
+ }
+
+ public void keycloakSaveRequest(Request request) throws IOException {
+ saveRequest(request, request.getSessionInternal(true));
+ }
+
+ public boolean keycloakRestoreRequest(Request request) {
+ try {
+ return restoreRequest(request, request.getSessionInternal());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected SamlSessionStore getTokenStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+ SamlSessionStore store = (SamlSessionStore)request.getNote(TOKEN_STORE_NOTE);
+ if (store != null) {
+ return store;
+ }
+
+ store = new CatalinaSamlSessionStore(userSessionManagement, createPrincipalFactory(), mapper, request, this, facade);
+
+ request.setNote(TOKEN_STORE_NOTE, store);
+ return store;
+ }
+
+}
diff --git a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlAuthenticator.java b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlAuthenticator.java
new file mode 100755
index 0000000000..2beb39cf8d
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlAuthenticator.java
@@ -0,0 +1,18 @@
+package org.keycloak.adapters.saml;
+
+import org.keycloak.adapters.HttpFacade;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class CatalinaSamlAuthenticator extends SamlAuthenticator {
+ public CatalinaSamlAuthenticator(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
+ super(facade, deployment, sessionStore);
+ }
+
+ @Override
+ protected void completeAuthentication(SamlSession account) {
+ // complete
+ }
+}
diff --git a/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
new file mode 100755
index 0000000000..4928a2627d
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
@@ -0,0 +1,193 @@
+package org.keycloak.adapters.saml;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.jboss.logging.Logger;
+import org.keycloak.adapters.HttpFacade;
+import org.keycloak.adapters.SessionIdMapper;
+import org.keycloak.adapters.tomcat.CatalinaUserSessionManagement;
+import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+import org.keycloak.util.KeycloakUriBuilder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class CatalinaSamlSessionStore implements SamlSessionStore {
+ protected static Logger log = Logger.getLogger(SamlSessionStore.class);
+ public static final String SAML_REDIRECT_URI = "SAML_REDIRECT_URI";
+
+ private final CatalinaUserSessionManagement sessionManagement;
+ protected final GenericPrincipalFactory principalFactory;
+ private final SessionIdMapper idMapper;
+ protected final Request request;
+ protected final AbstractSamlAuthenticatorValve valve;
+ protected final HttpFacade facade;
+
+ public CatalinaSamlSessionStore(CatalinaUserSessionManagement sessionManagement, GenericPrincipalFactory principalFactory,
+ SessionIdMapper idMapper, Request request, AbstractSamlAuthenticatorValve valve, HttpFacade facade) {
+ this.sessionManagement = sessionManagement;
+ this.principalFactory = principalFactory;
+ this.idMapper = idMapper;
+ this.request = request;
+ this.valve = valve;
+ this.facade = facade;
+ }
+
+ @Override
+ public void logoutAccount() {
+ Session sessionInternal = request.getSessionInternal(false);
+ if (sessionInternal == null) return;
+ HttpSession session = sessionInternal.getSession();
+ if (session != null) {
+ SamlSession samlSession = (SamlSession)session.getAttribute(SamlSession.class.getName());
+ if (samlSession != null) {
+ if (samlSession.getSessionIndex() != null) {
+ idMapper.removeSession(session.getId());
+ }
+ session.removeAttribute(SamlSession.class.getName());
+ }
+ session.removeAttribute(SAML_REDIRECT_URI);
+ }
+ sessionInternal.setPrincipal(null);
+ sessionInternal.setAuthType(null);
+ }
+
+ @Override
+ public void logoutByPrincipal(String principal) {
+ Set sessions = idMapper.getUserSessions(principal);
+ if (sessions != null) {
+ List ids = new LinkedList();
+ ids.addAll(sessions);
+ logoutSessionIds(ids);
+ for (String id : ids) {
+ idMapper.removeSession(id);
+ }
+ }
+
+ }
+
+ @Override
+ public void logoutBySsoId(List ssoIds) {
+ if (ssoIds == null) return;
+ List sessionIds = new LinkedList();
+ for (String id : ssoIds) {
+ String sessionId = idMapper.getSessionFromSSO(id);
+ if (sessionId != null) {
+ sessionIds.add(sessionId);
+ idMapper.removeSession(sessionId);
+ }
+
+ }
+ logoutSessionIds(sessionIds);
+ }
+
+ protected void logoutSessionIds(List sessionIds) {
+ if (sessionIds == null || sessionIds.isEmpty()) return;
+ Manager sessionManager = request.getContext().getManager();
+ sessionManagement.logoutHttpSessions(sessionManager, sessionIds);
+ }
+
+ @Override
+ public boolean isLoggedIn() {
+ Session session = request.getSessionInternal(false);
+ if (session == null) return false;
+ if (session == null) {
+ log.debug("session was null, returning null");
+ return false;
+ }
+ final SamlSession samlSession = (SamlSession)session.getSession().getAttribute(SamlSession.class.getName());
+ if (samlSession == null) {
+ log.debug("SamlSession was not in session, returning null");
+ return false;
+ }
+
+ GenericPrincipal principal = (GenericPrincipal) session.getPrincipal();
+ if (samlSession.getPrincipal().getName().equals(principal.getName()))
+ // in clustered environment in JBossWeb, principal is not serialized or saved
+ if (principal == null) {
+ principal = principalFactory.createPrincipal(request.getContext().getRealm(), samlSession.getPrincipal(), samlSession.getRoles());
+ session.setPrincipal(principal);
+ session.setAuthType("KEYCLOAK-SAML");
+
+ } else {
+ if (!principal.getUserPrincipal().getName().equals(samlSession.getPrincipal().getName())) {
+ throw new RuntimeException("Unknown State");
+ }
+ log.debug("************principal already in");
+ if (log.isDebugEnabled()) {
+ for (String role : principal.getRoles()) {
+ log.debug("principal role: " + role);
+ }
+ }
+
+ }
+ request.setUserPrincipal(principal);
+ request.setAuthType("KEYCLOAK-SAML");
+ restoreRequest();
+ return true;
+ }
+
+ @Override
+ public void saveAccount(SamlSession account) {
+ Session session = request.getSessionInternal(true);
+ session.getSession().setAttribute(SamlSession.class.getName(), account);
+ GenericPrincipal principal = (GenericPrincipal) session.getPrincipal();
+ // in clustered environment in JBossWeb, principal is not serialized or saved
+ if (principal == null) {
+ principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), account.getRoles());
+ session.setPrincipal(principal);
+ session.setAuthType("KEYCLOAK-SAML");
+
+ }
+ request.setUserPrincipal(principal);
+ request.setAuthType("KEYCLOAK-SAML");
+ idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), session.getId());
+
+ }
+
+ @Override
+ public SamlSession getAccount() {
+ HttpSession session = getSession(true);
+ return (SamlSession)session.getAttribute(SamlSession.class.getName());
+ }
+
+ @Override
+ public String getRedirectUri() {
+ return (String)getSession(true).getAttribute(SAML_REDIRECT_URI);
+ }
+
+ @Override
+ public void saveRequest() {
+ try {
+ valve.keycloakSaveRequest(request);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ getSession(true).setAttribute(SAML_REDIRECT_URI, facade.getRequest().getURI());
+
+ }
+
+ @Override
+ public boolean restoreRequest() {
+ getSession(true).removeAttribute(SAML_REDIRECT_URI);
+ return valve.keycloakRestoreRequest(request);
+ }
+
+ protected HttpSession getSession(boolean create) {
+ Session session = request.getSessionInternal(create);
+ if (session == null) return null;
+ return session.getSession();
+ }
+}
diff --git a/saml/client-adapter/tomcat/tomcat6/pom.xml b/saml/client-adapter/tomcat/tomcat6/pom.xml
new file mode 100755
index 0000000000..9c8e6aca4a
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat6/pom.xml
@@ -0,0 +1,76 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.6.0.Final-SNAPSHOT
+ ../../../../pom.xml
+
+ 4.0.0
+
+ keycloak-tomcat6-saml-adapter
+ Keycloak Tomcat 6 Saml Integration
+
+ 6.0.41
+
+
+
+
+
+ org.jboss.logging
+ jboss-logging
+ ${jboss.logging.version}
+
+
+ org.keycloak
+ keycloak-tomcat-core-saml-adapter
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+
+
+ org.apache.tomcat
+ tomcat-catalina
+
+
+ org.apache.tomcat
+ catalina
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+
+
+ org.apache.tomcat
+ catalina
+ ${tomcat.version}
+ provided
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+
+
+
diff --git a/saml/client-adapter/tomcat/tomcat6/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java b/saml/client-adapter/tomcat/tomcat6/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
new file mode 100755
index 0000000000..1541038de1
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat6/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
@@ -0,0 +1,60 @@
+package org.keycloak.adapters.saml.tomcat;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.keycloak.adapters.saml.AbstractSamlAuthenticatorValve;
+import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
+
+/**
+ * Keycloak authentication valve
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlAuthenticatorValve extends AbstractSamlAuthenticatorValve {
+ @Override
+ public boolean authenticate(Request request, Response response, LoginConfig config) throws IOException {
+ return authenticateInternal(request, response, config);
+ }
+
+ @Override
+ protected boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
+ if (loginConfig == null) return false;
+ LoginConfig config = (LoginConfig)loginConfig;
+ if (config.getErrorPage() == null) return false;
+ forwardToErrorPage(request, (Response)response, config);
+ return true;
+ }
+
+
+ @Override
+ public void start() throws LifecycleException {
+ StandardContext standardContext = (StandardContext) context;
+ standardContext.addLifecycleListener(this);
+ super.start();
+ }
+
+ public void logout(Request request) throws ServletException {
+ logoutInternal(request);
+ }
+
+ @Override
+ protected GenericPrincipalFactory createPrincipalFactory() {
+ return new GenericPrincipalFactory() {
+ @Override
+ protected GenericPrincipal createPrincipal(Principal userPrincipal, List roles) {
+ return new GenericPrincipal(null, userPrincipal.getName(), null, roles, userPrincipal, null);
+ }
+ };
+ }
+}
diff --git a/saml/client-adapter/tomcat/tomcat7/pom.xml b/saml/client-adapter/tomcat/tomcat7/pom.xml
new file mode 100755
index 0000000000..6a94f99f81
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat7/pom.xml
@@ -0,0 +1,84 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.6.0.Final-SNAPSHOT
+ ../../../../pom.xml
+
+ 4.0.0
+
+ keycloak-tomcat7-saml-adapter
+ Keycloak Tomcat 7 SAML Integration
+
+
+ 7.0.52
+
+
+
+
+
+ org.jboss.logging
+ jboss-logging
+ ${jboss.logging.version}
+
+
+ org.keycloak
+ keycloak-tomcat-core-saml-adapter
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+
+
+ org.apache.tomcat
+ tomcat-catalina
+
+
+ org.apache.tomcat
+ catalina
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+ ${tomcat.version}
+ provided
+
+
+ org.apache.tomcat
+ tomcat-catalina
+ ${tomcat.version}
+ provided
+
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+
+
+
diff --git a/saml/client-adapter/tomcat/tomcat7/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java b/saml/client-adapter/tomcat/tomcat7/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
new file mode 100755
index 0000000000..54f9a4226a
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat7/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
@@ -0,0 +1,56 @@
+package org.keycloak.adapters.saml.tomcat;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.keycloak.adapters.saml.AbstractSamlAuthenticatorValve;
+import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
+
+/**
+ * Keycloak authentication valve
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlAuthenticatorValve extends AbstractSamlAuthenticatorValve {
+ public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
+ return authenticateInternal(request, response, config);
+ }
+
+ @Override
+ protected boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
+ if (loginConfig == null) return false;
+ LoginConfig config = (LoginConfig)loginConfig;
+ if (config.getErrorPage() == null) return false;
+ forwardToErrorPage(request, (Response)response, config);
+ return true;
+ }
+
+
+ protected void initInternal() {
+ StandardContext standardContext = (StandardContext) context;
+ standardContext.addLifecycleListener(this);
+ }
+
+ public void logout(Request request) throws ServletException {
+ logoutInternal(request);
+ }
+
+ @Override
+ protected GenericPrincipalFactory createPrincipalFactory() {
+ return new GenericPrincipalFactory() {
+ @Override
+ protected GenericPrincipal createPrincipal(Principal userPrincipal, List roles) {
+ return new GenericPrincipal(userPrincipal.getName(), null, roles, userPrincipal, null);
+ }
+ };
+ }
+}
diff --git a/saml/client-adapter/tomcat/tomcat8/pom.xml b/saml/client-adapter/tomcat/tomcat8/pom.xml
new file mode 100755
index 0000000000..c3da5902fb
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat8/pom.xml
@@ -0,0 +1,83 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.6.0.Final-SNAPSHOT
+ ../../../../pom.xml
+
+ 4.0.0
+
+ keycloak-tomcat8-saml-adapter
+ Keycloak Tomcat 8 SAML Integration
+
+ 8.0.14
+
+
+
+
+
+ org.jboss.logging
+ jboss-logging
+ ${jboss.logging.version}
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+ ${tomcat.version}
+ provided
+
+
+ org.apache.tomcat
+ tomcat-catalina
+ ${tomcat.version}
+ provided
+
+
+
+ org.keycloak
+ keycloak-tomcat-core-saml-adapter
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+
+
+ org.apache.tomcat
+ tomcat-catalina
+
+
+ org.apache.tomcat
+ catalina
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+
+
+
diff --git a/saml/client-adapter/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java b/saml/client-adapter/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
new file mode 100755
index 0000000000..ead126a913
--- /dev/null
+++ b/saml/client-adapter/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
@@ -0,0 +1,71 @@
+package org.keycloak.adapters.saml.tomcat;
+
+import org.apache.catalina.authenticator.FormAuthenticator;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.tomcat.util.descriptor.web.LoginConfig;
+import org.keycloak.adapters.saml.AbstractSamlAuthenticatorValve;
+import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.security.Principal;
+import java.util.List;
+
+/**
+ * Keycloak authentication valve
+ *
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlAuthenticatorValve extends AbstractSamlAuthenticatorValve {
+ public boolean authenticate(Request request, HttpServletResponse response) throws IOException {
+ return authenticateInternal(request, response, request.getContext().getLoginConfig());
+ }
+
+ @Override
+ protected boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
+ if (loginConfig == null) return false;
+ LoginConfig config = (LoginConfig)loginConfig;
+ if (config.getErrorPage() == null) return false;
+ // had to do this to get around compiler/IDE issues :(
+ try {
+ Method method = null;
+ /*
+ for (Method m : getClass().getDeclaredMethods()) {
+ if (m.getName().equals("forwardToErrorPage")) {
+ method = m;
+ break;
+ }
+ }
+ */
+ method = FormAuthenticator.class.getDeclaredMethod("forwardToErrorPage", Request.class, HttpServletResponse.class, LoginConfig.class);
+ method.setAccessible(true);
+ method.invoke(this, request, response, config);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return true;
+ }
+
+ protected void initInternal() {
+ StandardContext standardContext = (StandardContext) context;
+ standardContext.addLifecycleListener(this);
+ }
+
+ public void logout(Request request) {
+ logoutInternal(request);
+ }
+
+ @Override
+ protected GenericPrincipalFactory createPrincipalFactory() {
+ return new GenericPrincipalFactory() {
+ @Override
+ protected GenericPrincipal createPrincipal(Principal userPrincipal, List roles) {
+ return new GenericPrincipal(userPrincipal.getName(), null, roles, userPrincipal, null);
+ }
+ };
+ }
+}
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
index 9521e0c5c7..6aae844da6 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
@@ -174,6 +174,7 @@ public class SamlService {
if (client == null) {
event.event(EventType.LOGIN);
+ event.client(issuer);
event.error(Errors.CLIENT_NOT_FOUND);
return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
new file mode 100755
index 0000000000..358fd23382
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
@@ -0,0 +1,138 @@
+package org.keycloak.testsuite.keycloaksaml;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlAdapterTest {
+
+ @ClassRule
+ public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
+ @Override
+ public void initWars() {
+ ClassLoader classLoader = SamlAdapterTest.class.getClassLoader();
+
+ initializeSamlSecuredWar("/keycloak-saml/simple-post", "/sales-post", "post.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/mappers", "/employee2", "employee2.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
+ initializeSamlSecuredWar("/keycloak-saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
+ SamlAdapterTestStrategy.uploadSP("http://localhost:8081/auth", this);
+ server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
+
+
+
+ }
+
+ @Override
+ public String getRealmJson() {
+ return "/keycloak-saml/testsaml.json";
+ }
+ };
+
+ @Rule
+ public SamlAdapterTestStrategy testStrategy = new SamlAdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8081", keycloakRule);
+
+ @Test
+ public void testPostBadRealmSignature() {
+ testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
+ @Override
+ public void check(WebDriver driver) {
+ Assert.assertTrue(driver.getPageSource().contains("Forbidden"));
+ }
+ });
+ }
+
+ @Test
+ public void testPostSimpleUnauthorized() {
+ testStrategy.testPostSimpleUnauthorized( new SamlAdapterTestStrategy.CheckAuthError() {
+ @Override
+ public void check(WebDriver driver) {
+ Assert.assertTrue(driver.getPageSource().contains("Forbidden"));
+ }
+ });
+ }
+
+ @Test
+ public void testMetadataPostSignedLoginLogout() throws Exception {
+ testStrategy.testMetadataPostSignedLoginLogout();
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogout() {
+ testStrategy.testRedirectSignedLoginLogout();
+ }
+
+ @Test
+ public void testPostSignedLoginLogoutEmailNameID() {
+ testStrategy.testPostSignedLoginLogoutEmailNameID();
+ }
+
+ @Test
+ public void testPostEncryptedLoginLogout() {
+ testStrategy.testPostEncryptedLoginLogout();
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFrontNoSSO() {
+ testStrategy.testRedirectSignedLoginLogoutFrontNoSSO();
+ }
+
+ @Test
+ public void testPostSimpleLoginLogout() {
+ testStrategy.testPostSimpleLoginLogout();
+ }
+
+ @Test
+ public void testPostSignedLoginLogoutTransientNameID() {
+ testStrategy.testPostSignedLoginLogoutTransientNameID();
+ }
+
+ @Test
+ public void testPostSimpleLoginLogoutIdpInitiated() {
+ testStrategy.testPostSimpleLoginLogoutIdpInitiated();
+ }
+
+ @Test
+ public void testAttributes() throws Exception {
+ testStrategy.testAttributes();
+ }
+
+ @Test
+ public void testPostSignedLoginLogoutPersistentNameID() {
+ testStrategy.testPostSignedLoginLogoutPersistentNameID();
+ }
+
+ @Test
+ public void testRelayStateEncoding() throws Exception {
+ testStrategy.testRelayStateEncoding();
+ }
+
+ @Test
+ public void testPostBadClientSignature() {
+ testStrategy.testPostBadClientSignature();
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFront() {
+ testStrategy.testRedirectSignedLoginLogoutFront();
+ }
+
+ @Test
+ public void testPostSignedLoginLogout() {
+ testStrategy.testPostSignedLoginLogout();
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
new file mode 100755
index 0000000000..6e0817b1c0
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
@@ -0,0 +1,409 @@
+package org.keycloak.testsuite.keycloaksaml;
+
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.keycloak.Config;
+import org.keycloak.adapters.saml.SamlPrincipal;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.oidc.TokenManager;
+import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
+import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
+import org.keycloak.protocol.saml.mappers.HardcodedRole;
+import org.keycloak.protocol.saml.mappers.RoleListMapper;
+import org.keycloak.protocol.saml.mappers.RoleNameMapper;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.admin.AdminRoot;
+import org.keycloak.testsuite.KeycloakServer;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.rule.AbstractKeycloakRule;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class SamlAdapterTestStrategy extends ExternalResource {
+ protected String AUTH_SERVER_URL = "http://localhost:8081/auth";
+ protected String APP_SERVER_BASE_URL = "http://localhost:8081";
+ protected AbstractKeycloakRule keycloakRule;
+
+ public SamlAdapterTestStrategy(String AUTH_SERVER_URL, String APP_SERVER_BASE_URL, AbstractKeycloakRule keycloakRule) {
+ this.AUTH_SERVER_URL = AUTH_SERVER_URL;
+ this.APP_SERVER_BASE_URL = APP_SERVER_BASE_URL;
+ this.keycloakRule = keycloakRule;
+ }
+
+ public WebRule webRule = new WebRule(this);
+
+
+ @WebResource
+ protected WebDriver driver;
+ @WebResource
+ protected LoginPage loginPage;
+
+ @Override
+ protected void before() throws Throwable {
+ super.before();
+ webRule.before();
+ }
+
+ @Override
+ protected void after() {
+ super.after();
+ webRule.after();
+ }
+
+ public static RealmModel baseAdapterTestInitialization(KeycloakSession session, RealmManager manager, RealmModel adminRealm, Class> clazz) {
+ RealmRepresentation representation = KeycloakServer.loadJson(clazz.getResourceAsStream("/keycloak-saml/testsaml.json"), RealmRepresentation.class);
+ RealmModel demoRealm = manager.importRealm(representation);
+ return demoRealm;
+ }
+
+
+
+ protected void checkLoggedOut(String mainUrl) {
+ String pageSource = driver.getPageSource();
+ System.out.println("*** logout pagesource ***");
+ System.out.println(pageSource);
+ System.out.println("driver url: " + driver.getCurrentUrl());
+ Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
+ driver.navigate().to(mainUrl);
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ }
+
+ public void testPostSimpleLoginLogout() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post/");
+ }
+
+ public void testPostSimpleUnauthorized(CheckAuthError error) {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("unauthorized", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post/");
+ System.out.println(driver.getPageSource());
+ error.check(driver);
+ }
+
+ public void testPostSimpleLoginLogoutIdpInitiated() {
+ driver.navigate().to(AUTH_SERVER_URL + "/realms/demo/protocol/saml/clients/sales-post");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post/");
+ }
+
+ public void testPostSignedLoginLogout() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-sig/");
+
+ }
+ public void testPostSignedLoginLogoutTransientNameID() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-transient/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-sig-transient/");
+ System.out.println(driver.getPageSource());
+ Assert.assertFalse(driver.getPageSource().contains("bburke"));
+ Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-transient?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-sig-transient/");
+
+ }
+ public void testPostSignedLoginLogoutPersistentNameID() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-persistent/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-sig-persistent/");
+ System.out.println(driver.getPageSource());
+ Assert.assertFalse(driver.getPageSource().contains("bburke"));
+ Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-persistent?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-sig-persistent/");
+
+ }
+ public void testPostSignedLoginLogoutEmailNameID() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-email/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-sig-email/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-email?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-sig-email/");
+
+ }
+
+ public void testRelayStateEncoding() throws Exception {
+ // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
+ // at the relay state
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ System.out.println(driver.getCurrentUrl());
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee/");
+ Assert.assertEquals(SamlSPFacade.sentRelayState, SamlSPFacade.RELAY_STATE);
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+
+ }
+
+ public void testAttributes() throws Exception {
+ {
+ SendUsernameServlet.sentPrincipal = null;
+ SendUsernameServlet.checkRoles = null;
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee2/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ List requiredRoles = new LinkedList<>();
+ requiredRoles.add("manager");
+ requiredRoles.add("employee");
+ requiredRoles.add("user");
+ SendUsernameServlet.checkRoles = requiredRoles;
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee2/");
+ SendUsernameServlet.checkRoles = null;
+ SamlPrincipal principal = (SamlPrincipal) SendUsernameServlet.sentPrincipal;
+ Assert.assertNotNull(principal);
+ Assert.assertEquals("bburke@redhat.com", principal.getAttribute(X500SAMLProfileConstants.EMAIL.get()));
+ Assert.assertEquals("bburke@redhat.com", principal.getFriendlyAttribute("email"));
+ Assert.assertEquals("617", principal.getAttribute("phone"));
+ Assert.assertNull(principal.getFriendlyAttribute("phone"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee2/?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/employee2/");
+
+ }
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ ClientModel app = appRealm.getClientByClientId(APP_SERVER_BASE_URL + "/employee2/");
+ for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
+ if (mapper.getName().equals("role-list")) {
+ app.removeProtocolMapper(mapper);
+ mapper.setId(null);
+ mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
+ mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
+ app.addProtocolMapper(mapper);
+ }
+ }
+ app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
+ app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
+ app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
+ app.addProtocolMapper(RoleNameMapper.create("renamed-employee-role", APP_SERVER_BASE_URL + "/employee/.employee", "pee-on"));
+ }
+ }, "demo");
+
+ System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");
+
+ {
+ SendUsernameServlet.sentPrincipal = null;
+ SendUsernameServlet.checkRoles = null;
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee2/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ List requiredRoles = new LinkedList<>();
+ requiredRoles.add("el-jefe");
+ requiredRoles.add("user");
+ requiredRoles.add("hardcoded-role");
+ requiredRoles.add("pee-on");
+ SendUsernameServlet.checkRoles = requiredRoles;
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee2/");
+ SendUsernameServlet.checkRoles = null;
+ SamlPrincipal principal = (SamlPrincipal) SendUsernameServlet.sentPrincipal;
+ Assert.assertNotNull(principal);
+ Assert.assertEquals("hard", principal.getAttribute("hardcoded-attribute"));
+
+
+ }
+ }
+
+ public void testRedirectSignedLoginLogout() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/employee-sig/");
+
+ }
+
+ public void testRedirectSignedLoginLogoutFrontNoSSO() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig-front/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee-sig-front/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig-front?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/employee-sig-front/");
+
+ }
+
+ public void testRedirectSignedLoginLogoutFront() {
+ // visit 1st app an logg in
+ System.out.println("visit 1st app ");
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ System.out.println("login to form");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // visit 2nd app
+ System.out.println("visit 2nd app ");
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig-front/");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/employee-sig-front/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // visit 3rd app
+ System.out.println("visit 3rd app ");
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // logout of first app
+ System.out.println("GLO");
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/employee-sig/");
+ driver.navigate().to(APP_SERVER_BASE_URL + "/employee-sig-front/");
+ String currentUrl = driver.getCurrentUrl();
+ Assert.assertTrue(currentUrl.startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
+
+ }
+
+ public void testPostEncryptedLoginLogout() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-enc/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-enc/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-enc?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-enc/");
+
+ }
+ public void testPostBadClientSignature() {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/bad-client-sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ Assert.assertEquals(driver.getTitle(), "We're sorry...");
+
+ }
+ public static interface CheckAuthError {
+ void check(WebDriver driver);
+ }
+
+ public void testPostBadRealmSignature(CheckAuthError error) {
+ driver.navigate().to(APP_SERVER_BASE_URL + "/bad-realm-sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/bad-realm-sales-post-sig/");
+ System.out.println(driver.getPageSource());
+ error.check(driver);
+ }
+
+ private static String createToken(String AUTH_SERVER_URL, AbstractKeycloakRule keycloakRule) {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+
+ RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
+ ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
+ TokenManager tm = new TokenManager();
+ UserModel admin = session.users().getUserByUsername("admin", adminRealm);
+ ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, AUTH_SERVER_URL + "/realms/master");
+ UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, true, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
+ return tm.encodeToken(adminRealm, token);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ public void testMetadataPostSignedLoginLogout() throws Exception {
+
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-metadata/");
+ Assert.assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-metadata/");
+ String pageSource = driver.getPageSource();
+ Assert.assertTrue(pageSource.contains("bburke"));
+ driver.navigate().to(APP_SERVER_BASE_URL + "/sales-metadata?GLO=true");
+ checkLoggedOut(APP_SERVER_BASE_URL + "/sales-metadata/");
+
+ }
+
+ public static void uploadSP(String AUTH_SERVER_URL, AbstractKeycloakRule keycloakRule) {
+ String token = createToken(AUTH_SERVER_URL, keycloakRule);
+ final String authHeader = "Bearer " + token;
+ ClientRequestFilter authFilter = new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
+ }
+ };
+ Client client = ClientBuilder.newBuilder().register(authFilter).build();
+ UriBuilder authBase = UriBuilder.fromUri(AUTH_SERVER_URL + "");
+ WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
+
+
+ MultipartFormDataOutput formData = new MultipartFormDataOutput();
+ InputStream is = SamlAdapterTestStrategy.class.getResourceAsStream("/keycloak-saml/sp-metadata.xml");
+ Assert.assertNotNull(is);
+ formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
+
+ WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload");
+ System.out.println(upload.getUri());
+ Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA));
+ Assert.assertEquals(204, response.getStatus());
+ response.close();
+ client.close();
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java
deleted file mode 100755
index f51c15a713..0000000000
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java
+++ /dev/null
@@ -1,450 +0,0 @@
-package org.keycloak.testsuite.keycloaksaml;
-
-import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.Config;
-import org.keycloak.adapters.saml.SamlPrincipal;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientSessionModel;
-import org.keycloak.models.Constants;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ProtocolMapperModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.TokenManager;
-import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
-import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
-import org.keycloak.protocol.saml.mappers.HardcodedRole;
-import org.keycloak.protocol.saml.mappers.RoleListMapper;
-import org.keycloak.protocol.saml.mappers.RoleNameMapper;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.admin.AdminRoot;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.openqa.selenium.WebDriver;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SamlBindingTest {
-
- @ClassRule
- public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
- @Override
- public void initWars() {
- ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
-
- initializeSamlSecuredWar("/keycloak-saml/simple-post", "/sales-post", "post.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/mappers", "/employee2", "employee2.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
- initializeSamlSecuredWar("/keycloak-saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
- uploadSP();
- server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
-
-
-
- }
-
- @Override
- public String getRealmJson() {
- return "/keycloak-saml/testsaml.json";
- }
- };
-
- public static class SamlSPFacade extends HttpServlet {
- public static String samlResponse;
- public static String RELAY_STATE = "http://test.com/foo/bar";
- public static String sentRelayState;
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- handler(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- handler(req, resp);
- }
-
- private void handler(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("********* HERE ******");
- if (req.getParameterMap().isEmpty()) {
- System.out.println("redirecting");
- resp.setStatus(302);
- // Redirect
- // UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVLRTsIwFP2Vpe%2BjG4wxG0YyWYxL0BBAH3wx3XYnTbp29nYof%2B8YEvEBNOlD03vOveec2ynyWjYsae1WreC9BbTOZy0Vsr4Qk9YopjkKZIrXgMwWbJ08LNhw4LHGaKsLLcmRch3MEcFYoRVxktN1rhW2NZg1mJ0o4Gm1iMnW2oZRKnXB5VajZZEX%2BRTqRuo9ACVO2mkUih%2F4l9C8s0MNcFkjLaHW9KSUHlwR506bAnrPMam4RCBOlsYkS1%2BD3MvLcDJxAx9KN4jCkXszrG5cP%2BCVH4y8IM8PYFx2dsQOfuiILWQKLVc2JkPPH7te6HrRxh%2BzUdidwSSIXoiz%2FBZyK1Qp1Nv1yPIjCNn9ZrN0V1AKA4UlzjMY7N13IDKbHjyxXoA5291%2FtzH7I%2FApPet%2FHNawx65hli61FMXeSaTUH%2FMubtvlYU0LfcA1t5cl%2BAO%2FfxGlW%2FVQ1ipsoBCVgJLQ2XHo7385%2BwI%3D");
- UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
- builder.queryParam("RelayState", RELAY_STATE);
- resp.setHeader("Location", builder.build().toString());
- return;
- }
- System.out.println("received response");
- samlResponse = req.getParameter("SAMLResponse");
- sentRelayState = req.getParameter("RelayState");
- }
- }
-
- @Rule
- public WebRule webRule = new WebRule(this);
- @WebResource
- protected WebDriver driver;
- @WebResource
- protected LoginPage loginPage;
-
- protected void checkLoggedOut(String mainUrl) {
- String pageSource = driver.getPageSource();
- System.out.println("*** logout pagesource ***");
- System.out.println(pageSource);
- System.out.println("driver url: " + driver.getCurrentUrl());
- Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
- driver.navigate().to(mainUrl);
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- }
-
- //@Test
- public void ideTesting() throws Exception {
- Thread.sleep(100000000);
- }
-
- @Test
- public void testPostSimpleLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post/");
- }
- @Test
- public void testPostSimpleLoginLogoutIdpInitiated() {
- driver.navigate().to("http://localhost:8081/auth/realms/demo/protocol/saml/clients/sales-post");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post/");
- }
-
- @Test
- public void testPostSignedLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig/");
-
- }
- @Test
- public void testPostSignedLoginLogoutTransientNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-transient/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/");
- System.out.println(driver.getPageSource());
- Assert.assertFalse(driver.getPageSource().contains("bburke"));
- Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-transient/");
-
- }
- @Test
- public void testPostSignedLoginLogoutPersistentNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/");
- System.out.println(driver.getPageSource());
- Assert.assertFalse(driver.getPageSource().contains("bburke"));
- Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/");
-
- }
- @Test
- public void testPostSignedLoginLogoutEmailNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-email/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-email/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-email/");
-
- }
-
- @Test
- public void testRelayStateEncoding() throws Exception {
- // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
- // at the relay state
- SamlSPFacade.samlResponse = null;
- driver.navigate().to("http://localhost:8081/employee/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- System.out.println(driver.getCurrentUrl());
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
- Assert.assertEquals(SamlSPFacade.sentRelayState, SamlSPFacade.RELAY_STATE);
- Assert.assertNotNull(SamlSPFacade.samlResponse);
-
- }
-
- @Test
- public void testAttributes() throws Exception {
- {
- SamlKeycloakRule.SendUsernameServlet.sentPrincipal = null;
- SamlKeycloakRule.SendUsernameServlet.checkRoles = null;
- driver.navigate().to("http://localhost:8081/employee2/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- List requiredRoles = new LinkedList<>();
- requiredRoles.add("manager");
- requiredRoles.add("employee");
- requiredRoles.add("user");
- SamlKeycloakRule.SendUsernameServlet.checkRoles = requiredRoles;
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee2/");
- SamlKeycloakRule.SendUsernameServlet.checkRoles = null;
- SamlPrincipal principal = (SamlPrincipal)SamlKeycloakRule.SendUsernameServlet.sentPrincipal;
- Assert.assertNotNull(principal);
- Assert.assertEquals("bburke@redhat.com", principal.getAttribute(X500SAMLProfileConstants.EMAIL.get()));
- Assert.assertEquals("bburke@redhat.com", principal.getFriendlyAttribute("email"));
- Assert.assertEquals("617", principal.getAttribute("phone"));
- Assert.assertNull(principal.getFriendlyAttribute("phone"));
- driver.navigate().to("http://localhost:8081/employee2/?GLO=true");
- checkLoggedOut("http://localhost:8081/employee2/");
-
- }
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee2/");
- for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
- if (mapper.getName().equals("role-list")) {
- app.removeProtocolMapper(mapper);
- mapper.setId(null);
- mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
- mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
- app.addProtocolMapper(mapper);
- }
- }
- app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
- app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
- app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
- app.addProtocolMapper(RoleNameMapper.create("renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
- }
- }, "demo");
-
- System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");
-
- {
- SamlKeycloakRule.SendUsernameServlet.sentPrincipal = null;
- SamlKeycloakRule.SendUsernameServlet.checkRoles = null;
- driver.navigate().to("http://localhost:8081/employee2/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- List requiredRoles = new LinkedList<>();
- requiredRoles.add("el-jefe");
- requiredRoles.add("user");
- requiredRoles.add("hardcoded-role");
- requiredRoles.add("pee-on");
- SamlKeycloakRule.SendUsernameServlet.checkRoles = requiredRoles;
- SamlKeycloakRule.SendUsernameServlet.checkRoles = requiredRoles;
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee2/");
- SamlKeycloakRule.SendUsernameServlet.checkRoles = null;
- SamlPrincipal principal = (SamlPrincipal)SamlKeycloakRule.SendUsernameServlet.sentPrincipal;
- Assert.assertNotNull(principal);
- Assert.assertEquals("hard", principal.getAttribute("hardcoded-attribute"));
-
-
- }
- }
-
- @Test
- public void testRedirectSignedLoginLogout() {
- driver.navigate().to("http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig/");
-
- }
-
- @Test
- public void testRedirectSignedLoginLogoutFrontNoSSO() {
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig-front/");
-
- }
-
- @Test
- public void testRedirectSignedLoginLogoutFront() {
- // visit 1st app an logg in
- System.out.println("visit 1st app ");
- driver.navigate().to("http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- System.out.println("login to form");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // visit 2nd app
- System.out.println("visit 2nd app ");
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // visit 3rd app
- System.out.println("visit 3rd app ");
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // logout of first app
- System.out.println("GLO");
- driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig/");
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- String currentUrl = driver.getCurrentUrl();
- Assert.assertTrue(currentUrl.startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
-
- }
-
- @Test
- public void testPostEncryptedLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post-enc/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-enc/");
-
- }
- @Test
- public void testPostBadClientSignature() {
- driver.navigate().to("http://localhost:8081/bad-client-sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- Assert.assertEquals(driver.getTitle(), "We're sorry...");
-
- }
-
- @Test
- public void testPostBadRealmSignature() {
- driver.navigate().to("http://localhost:8081/bad-realm-sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/bad-realm-sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("null"));
- }
-
- private static String createToken() {
- KeycloakSession session = keycloakRule.startSession();
- try {
- RealmManager manager = new RealmManager(session);
-
- RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
- ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
- TokenManager tm = new TokenManager();
- UserModel admin = session.users().getUserByUsername("admin", adminRealm);
- ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
- clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
- UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
- AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, true, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
- return tm.encodeToken(adminRealm, token);
- } finally {
- keycloakRule.stopSession(session, true);
- }
- }
-
-
- @Test
- public void testMetadataPostSignedLoginLogout() throws Exception {
-
- driver.navigate().to("http://localhost:8081/sales-metadata/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-metadata/");
- String pageSource = driver.getPageSource();
- Assert.assertTrue(pageSource.contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-metadata/");
-
- }
-
- public static void uploadSP() {
- String token = createToken();
- final String authHeader = "Bearer " + token;
- ClientRequestFilter authFilter = new ClientRequestFilter() {
- @Override
- public void filter(ClientRequestContext requestContext) throws IOException {
- requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
- }
- };
- Client client = ClientBuilder.newBuilder().register(authFilter).build();
- UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
- WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
-
-
- MultipartFormDataOutput formData = new MultipartFormDataOutput();
- InputStream is = SamlBindingTest.class.getResourceAsStream("/keycloak-saml/sp-metadata.xml");
- Assert.assertNotNull(is);
- formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
-
- WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload");
- System.out.println(upload.getUri());
- Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA));
- Assert.assertEquals(204, response.getStatus());
- response.close();
- client.close();
- }
-}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
index e7889afc3d..34d17f0aff 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
@@ -12,20 +12,11 @@ import io.undertow.servlet.api.LoginConfig;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.ServletInfo;
import io.undertow.servlet.api.WebResourceCollection;
-import org.junit.Assert;
import org.keycloak.adapters.saml.undertow.SamlServletExtension;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
-import org.picketlink.identity.federation.bindings.wildfly.sp.SPServletExtension;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.io.OutputStream;
import java.net.URL;
-import java.security.Principal;
-import java.util.List;
/**
* @author Bill Burke
@@ -33,61 +24,6 @@ import java.util.List;
*/
public abstract class SamlKeycloakRule extends AbstractKeycloakRule {
- public static class SendUsernameServlet extends HttpServlet {
-
- public static Principal sentPrincipal;
- public static List checkRoles;
-
- @Override
- protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
- if (checkRoles != null) {
- for (String role : checkRoles) {
- System.out.println("check role: " + role);
- Assert.assertTrue(req.isUserInRole(role));
- }
-
- }
- resp.setContentType("text/plain");
- OutputStream stream = resp.getOutputStream();
- Principal principal = req.getUserPrincipal();
- stream.write("request-path: ".getBytes());
- stream.write(req.getPathInfo().getBytes());
- stream.write("\n".getBytes());
- stream.write("principal=".getBytes());
- if (principal == null) {
- stream.write("null".getBytes());
- return;
- }
- String name = principal.getName();
- stream.write(name.getBytes());
- sentPrincipal = principal;
-
- }
- @Override
- protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
- if (checkRoles != null) {
- for (String role : checkRoles) {
- Assert.assertTrue(req.isUserInRole(role));
- }
-
- }
- resp.setContentType("text/plain");
- OutputStream stream = resp.getOutputStream();
- Principal principal = req.getUserPrincipal();
- stream.write("request-path: ".getBytes());
- stream.write(req.getPathInfo().getBytes());
- stream.write("\n".getBytes());
- stream.write("principal=".getBytes());
- if (principal == null) {
- stream.write("null".getBytes());
- return;
- }
- String name = principal.getName();
- stream.write(name.getBytes());
- sentPrincipal = principal;
- }
- }
-
public static class TestResourceManager implements ResourceManager {
private final String basePath;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlSPFacade.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlSPFacade.java
new file mode 100755
index 0000000000..a03fb8f2d5
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlSPFacade.java
@@ -0,0 +1,45 @@
+package org.keycloak.testsuite.keycloaksaml;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.UriBuilder;
+import java.io.IOException;
+
+/**
+* @author Bill Burke
+* @version $Revision: 1 $
+*/
+public class SamlSPFacade extends HttpServlet {
+ public static String samlResponse;
+ public static String RELAY_STATE = "http://test.com/foo/bar";
+ public static String sentRelayState;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ handler(req, resp);
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ handler(req, resp);
+ }
+
+ private void handler(HttpServletRequest req, HttpServletResponse resp) {
+ System.out.println("********* HERE ******");
+ if (req.getParameterMap().isEmpty()) {
+ System.out.println("redirecting");
+ resp.setStatus(302);
+ // Redirect
+ // UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVLRTsIwFP2Vpe%2BjG4wxG0YyWYxL0BBAH3wx3XYnTbp29nYof%2B8YEvEBNOlD03vOveec2ynyWjYsae1WreC9BbTOZy0Vsr4Qk9YopjkKZIrXgMwWbJ08LNhw4LHGaKsLLcmRch3MEcFYoRVxktN1rhW2NZg1mJ0o4Gm1iMnW2oZRKnXB5VajZZEX%2BRTqRuo9ACVO2mkUih%2F4l9C8s0MNcFkjLaHW9KSUHlwR506bAnrPMam4RCBOlsYkS1%2BD3MvLcDJxAx9KN4jCkXszrG5cP%2BCVH4y8IM8PYFx2dsQOfuiILWQKLVc2JkPPH7te6HrRxh%2BzUdidwSSIXoiz%2FBZyK1Qp1Nv1yPIjCNn9ZrN0V1AKA4UlzjMY7N13IDKbHjyxXoA5291%2FtzH7I%2FApPet%2FHNawx65hli61FMXeSaTUH%2FMubtvlYU0LfcA1t5cl%2BAO%2FfxGlW%2FVQ1ipsoBCVgJLQ2XHo7385%2BwI%3D");
+ UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
+ builder.queryParam("RelayState", RELAY_STATE);
+ resp.setHeader("Location", builder.build().toString());
+ return;
+ }
+ System.out.println("received response");
+ samlResponse = req.getParameter("SAMLResponse");
+ sentRelayState = req.getParameter("RelayState");
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SendUsernameServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SendUsernameServlet.java
new file mode 100755
index 0000000000..faa50146a9
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SendUsernameServlet.java
@@ -0,0 +1,74 @@
+package org.keycloak.testsuite.keycloaksaml;
+
+import org.junit.Assert;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.Principal;
+import java.util.List;
+
+/**
+* @author Bill Burke
+* @version $Revision: 1 $
+*/
+public class SendUsernameServlet extends HttpServlet {
+
+ public static Principal sentPrincipal;
+ public static List checkRoles;
+
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ System.out.println("In SendUsername Servlet doGet()");
+ if (checkRoles != null) {
+ for (String role : checkRoles) {
+ System.out.println("check role: " + role);
+ Assert.assertTrue(req.isUserInRole(role));
+ }
+
+ }
+ resp.setContentType("text/plain");
+ OutputStream stream = resp.getOutputStream();
+ Principal principal = req.getUserPrincipal();
+ stream.write("request-path: ".getBytes());
+ stream.write(req.getPathInfo().getBytes());
+ stream.write("\n".getBytes());
+ stream.write("principal=".getBytes());
+ if (principal == null) {
+ stream.write("null".getBytes());
+ return;
+ }
+ String name = principal.getName();
+ stream.write(name.getBytes());
+ sentPrincipal = principal;
+
+ }
+ @Override
+ protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ System.out.println("In SendUsername Servlet doPost()");
+ if (checkRoles != null) {
+ for (String role : checkRoles) {
+ System.out.println("check role: " + role);
+ Assert.assertTrue(req.isUserInRole(role));
+ }
+
+ }
+ resp.setContentType("text/plain");
+ OutputStream stream = resp.getOutputStream();
+ Principal principal = req.getUserPrincipal();
+ stream.write("request-path: ".getBytes());
+ stream.write(req.getPathInfo().getBytes());
+ stream.write("\n".getBytes());
+ stream.write("principal=".getBytes());
+ if (principal == null) {
+ stream.write("null".getBytes());
+ return;
+ }
+ String name = principal.getName();
+ stream.write(name.getBytes());
+ sentPrincipal = principal;
+ }
+}
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
index 5fafa8e7e1..8d5576e30f 100755
--- a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
+++ b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
@@ -21,7 +21,7 @@
"email" : "bburke@redhat.com",
"credentials" : [
{ "type" : "password",
- "value" : "password" }
+ "value" : "password" }
],
"attributes" : {
"phone": "617"
@@ -31,6 +31,15 @@
"http://localhost:8081/employee/": [ "employee" ],
"http://localhost:8081/employee2/": [ "employee" ]
}
+ },
+ {
+ "username" : "unauthorized",
+ "enabled": true,
+ "email" : "unauthorized@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ]
}
],
"applications": [
diff --git a/testsuite/tomcat6/pom.xml b/testsuite/tomcat6/pom.xml
index 498c4d61e6..7d05f4d196 100755
--- a/testsuite/tomcat6/pom.xml
+++ b/testsuite/tomcat6/pom.xml
@@ -103,6 +103,24 @@
org.keycloak
keycloak-tomcat6-adapter
+
+
+ org.keycloak
+ keycloak-tomcat6-saml-adapter
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+
+
+ org.apache.tomcat
+ tomcat-catalina
+
+
+ org.apache.tomcat
+ catalina
+
+
io.undertow
diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
new file mode 100755
index 0000000000..98eec5a2f8
--- /dev/null
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatSamlTest.java
@@ -0,0 +1,193 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.testsuite;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.adapter.AdapterTestStrategy;
+import org.keycloak.testsuite.keycloaksaml.SamlAdapterTestStrategy;
+import org.keycloak.testsuite.rule.AbstractKeycloakRule;
+import org.openqa.selenium.WebDriver;
+
+import java.io.File;
+import java.net.URL;
+import java.util.regex.Matcher;
+
+/**
+ * @author Stian Thorgersen
+ */
+public class TomcatSamlTest {
+ @ClassRule
+ public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
+ @Override
+ protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
+ SamlAdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
+ }
+ };
+
+ static TomcatServer tomcat = null;
+
+ @BeforeClass
+ public static void initTomcat() throws Exception {
+ URL dir = TomcatSamlTest.class.getResource("/keycloak-saml/testsaml.json");
+ String baseDir = new File(dir.getFile()).getParentFile().toString();
+ System.out.println("Tomcat basedir: " + baseDir);
+ tomcat = new TomcatServer(8082, baseDir);
+ System.setProperty("app.server.base.url", "http://localhost:8082");
+ System.setProperty("my.host.name", "localhost");
+ tomcat.deploySaml("/sales-post", "simple-post");
+ tomcat.deploySaml("/sales-post-sig", "signed-post");
+ tomcat.deploySaml("/sales-post-sig-email", "signed-post-email");
+ tomcat.deploySaml("/sales-post-sig-transient", "signed-post-transient");
+ tomcat.deploySaml("/sales-post-sig-persistent", "signed-post-persistent");
+ tomcat.deploySaml("/sales-metadata", "signed-metadata");
+ tomcat.deploySaml("/employee-sig", "signed-get");
+ tomcat.deploySaml("/employee2", "mappers");
+ tomcat.deploySaml("/employee-sig-front", "signed-front-get");
+ tomcat.deploySaml("/bad-client-sales-post-sig", "bad-client-signed-post");
+ tomcat.deploySaml("/bad-realm-sales-post-sig", "bad-realm-signed-post");
+ tomcat.deploySaml("/sales-post-enc", "encrypted-post");
+ SamlAdapterTestStrategy.uploadSP("http://localhost:8081/auth", keycloakRule);
+
+
+ tomcat.start();
+ //tomcat.getServer().await();
+ }
+
+ @AfterClass
+ public static void shutdownTomcat() throws Exception {
+ tomcat.stop();
+ }
+
+ @Rule
+ public SamlAdapterTestStrategy testStrategy = new SamlAdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8082", keycloakRule);
+
+ @Test
+ public void testPostSimpleLoginLogout() {
+ testStrategy.testPostSimpleLoginLogout();
+ }
+
+ @Test
+ public void testPostSimpleLoginLogoutIdpInitiated() {
+ testStrategy.testPostSimpleLoginLogoutIdpInitiated();
+ }
+
+ @Test
+ public void testPostSignedLoginLogout() {
+ testStrategy.testPostSignedLoginLogout();
+ }
+
+ @Test
+ public void testPostSignedLoginLogoutTransientNameID() {
+ testStrategy.testPostSignedLoginLogoutTransientNameID();
+ }
+
+ @Test
+ public void testPostSignedLoginLogoutPersistentNameID() {
+ testStrategy.testPostSignedLoginLogoutPersistentNameID();
+ }
+
+ @Test
+ public void testPostSignedLoginLogoutEmailNameID() {
+ testStrategy.testPostSignedLoginLogoutEmailNameID();
+ }
+
+ @Test
+ public void testAttributes() throws Exception {
+ testStrategy.testAttributes();
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogout() {
+ testStrategy.testRedirectSignedLoginLogout();
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFrontNoSSO() {
+ testStrategy.testRedirectSignedLoginLogoutFrontNoSSO();
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFront() {
+ testStrategy.testRedirectSignedLoginLogoutFront();
+ }
+
+ @Test
+ public void testPostEncryptedLoginLogout() {
+ testStrategy.testPostEncryptedLoginLogout();
+ }
+
+ @Test
+ public void testPostBadClientSignature() {
+ testStrategy.testPostBadClientSignature();
+ }
+
+ @Test
+ public void testPostBadRealmSignature() {
+ testStrategy.testPostBadRealmSignature( new SamlAdapterTestStrategy.CheckAuthError() {
+ @Override
+ public void check(WebDriver driver) {
+ Assert.assertEquals(driver.getPageSource(), "");
+ }
+ });
+ }
+
+ @Test
+ public void testPostSimpleUnauthorized() {
+ testStrategy.testPostSimpleUnauthorized( new SamlAdapterTestStrategy.CheckAuthError() {
+ @Override
+ public void check(WebDriver driver) {
+ Assert.assertTrue(driver.getPageSource().contains("forbidden"));
+ }
+ });
+ }
+
+ //@Test
+ public void testMetadataPostSignedLoginLogout() throws Exception {
+ testStrategy.testMetadataPostSignedLoginLogout();
+ }
+
+ static String getBaseDirectory() {
+ String dirPath = null;
+ String relativeDirPath = "testsuite" + File.separator + "tomcat6" + File.separator + "target";
+
+ if (System.getProperties().containsKey("maven.home")) {
+ dirPath = System.getProperty("user.dir").replaceFirst("testsuite.tomcat6.*", Matcher.quoteReplacement(relativeDirPath));
+ } else {
+ for (String c : System.getProperty("java.class.path").split(File.pathSeparator)) {
+ if (c.contains(File.separator + "testsuite" + File.separator + "tomcat6")) {
+ dirPath = c.replaceFirst("testsuite.tomcat6.*", Matcher.quoteReplacement(relativeDirPath));
+ break;
+ }
+ }
+ }
+ String absolutePath = new File(dirPath).getAbsolutePath();
+ return absolutePath;
+ }
+}
diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java
index a0ebb08547..df17d9b1be 100755
--- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatServer.java
@@ -7,6 +7,7 @@ import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Embedded;
import org.jboss.logging.Logger;
+import org.keycloak.adapters.saml.tomcat.SamlAuthenticatorValve;
import org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve;
public class TomcatServer {
@@ -40,7 +41,7 @@ public class TomcatServer {
public TomcatServer(int port, String appBase) {
this.port = port;
-
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
server = new Embedded();
server.setName("TomcatEmbeddedServer");
server.setCatalinaBase(TomcatTest.getBaseDirectory());
@@ -64,6 +65,20 @@ public class TomcatServer {
rootContext.setDefaultWebXml("web.xml");
host.addChild(rootContext);
}
+ public void deploySaml(String contextPath, String appDir) {
+ if (contextPath == null) {
+ throw new IllegalArgumentException("Context path or appbase should not be null");
+ }
+ if (!contextPath.startsWith("/")) {
+ contextPath = "/" + contextPath;
+ }
+ StandardContext rootContext = (StandardContext) server.createContext(contextPath, appDir);
+ SamlAuthenticatorValve valve = new SamlAuthenticatorValve();
+ rootContext.addValve(valve);
+ //rootContext.addLifecycleListener(valve);
+ rootContext.setDefaultWebXml("web.xml");
+ host.addChild(rootContext);
+ }
/**
* Start the tomcat embedded server
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 e28a2f6308..9e0101dccd 100755
--- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
@@ -24,6 +24,7 @@ package org.keycloak.testsuite;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.KeycloakSession;
@@ -39,6 +40,7 @@ import java.util.regex.Matcher;
/**
* @author Stian Thorgersen
*/
+//@Ignore
public class TomcatTest {
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..fa1b2593d4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..6a3e3ba7d3
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-client-signed-post/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..8b1bf3d783
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..215384cdef
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/bad-realm-signed-post/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/context.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/context.xml
new file mode 100755
index 0000000000..d16faafd19
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/context.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..24bfb6454a
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..822162ceaf
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/encrypted-post/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/mappers/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/mappers/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..4fc1dfc640
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/mappers/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/mappers/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/mappers/WEB-INF/web.xml
new file mode 100755
index 0000000000..0d92eb3cab
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/mappers/WEB-INF/web.xml
@@ -0,0 +1,56 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+ el-jefe
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
+ user
+
+
+ employee
+
+
+ pee-on
+
+
+ hardcoded-role
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..a8d84c17fe
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..4daad218a3
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..724919bd9b
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..4daad218a3
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-get/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..1ffeb1bdd3
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..144830bc77
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-metadata/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..dbb9c31b6f
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..144830bc77
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..0415bb1dd1
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..144830bc77
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..4b96159674
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..144830bc77
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..dcd6f5b0e4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/keystore.jks b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/keystore.jks
new file mode 100755
index 0000000000..144830bc77
Binary files /dev/null and b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/keystore.jks differ
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/signed-post/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000000..e831ff7e3f
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/simple-post/WEB-INF/web.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/simple-post/WEB-INF/web.xml
new file mode 100755
index 0000000000..86db4a46a4
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/simple-post/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ adapter-test
+
+
+ SendUsernameServlet
+ org.keycloak.testsuite.keycloaksaml.SendUsernameServlet
+
+
+ SendUsernameServlet
+ /*
+
+
+
+
+ Users
+ /*
+
+
+ manager
+
+
+
+
+ BASIC
+ demo
+
+ /error.html
+ /error.html
+
+
+
+
+ manager
+
+
+ el-jefe
+
+
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/sp-metadata.xml b/testsuite/tomcat6/src/test/resources/keycloak-saml/sp-metadata.xml
new file mode 100755
index 0000000000..8f143deb61
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/sp-metadata.xml
@@ -0,0 +1,38 @@
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+
+
+
+
+
+
+
+ MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==
+
+
+
+
+
+
+ JBoss
+ JBoss by Red Hat
+ http://localhost:8080/sales-metadata/
+
+
+ The
+ Admin
+ admin@mycompany.com
+
+
+
\ No newline at end of file
diff --git a/testsuite/tomcat6/src/test/resources/keycloak-saml/testsaml.json b/testsuite/tomcat6/src/test/resources/keycloak-saml/testsaml.json
new file mode 100755
index 0000000000..0b13fb9e9e
--- /dev/null
+++ b/testsuite/tomcat6/src/test/resources/keycloak-saml/testsaml.json
@@ -0,0 +1,376 @@
+{
+ "id": "demo",
+ "realm": "demo",
+ "enabled": true,
+ "sslRequired": "external",
+ "registrationAllowed": true,
+ "resetPasswordAllowed": true,
+ "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
+ "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "requiredCredentials": [ "password" ],
+ "defaultRoles": [ "user" ],
+ "smtpServer": {
+ "from": "auto@keycloak.org",
+ "host": "localhost",
+ "port":"3025"
+ },
+ "users" : [
+ {
+ "username" : "bburke",
+ "enabled": true,
+ "email" : "bburke@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ],
+ "attributes" : {
+ "phone": "617"
+ },
+ "realmRoles": ["manager", "user"],
+ "applicationRoles": {
+ "http://localhost:8082/employee/": [ "employee" ],
+ "http://localhost:8082/employee2/": [ "employee" ]
+ }
+ } ,
+ {
+ "username" : "unauthorized",
+ "enabled": true,
+ "email" : "unauthorized@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ]
+ }
+ ],
+ "applications": [
+ {
+ "name": "http://localhost:8082/sales-post/",
+ "enabled": true,
+ "fullScopeAllowed": true,
+ "protocol": "saml",
+ "baseUrl": "http://localhost:8082/sales-post",
+ "redirectUris": [
+ "http://localhost:8082/sales-post/*"
+ ],
+ "attributes": {
+ "saml.authnstatement": "true",
+ "saml_assertion_consumer_url_post": "http://localhost:8082/sales-post/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/sales-post/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/sales-post/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/sales-post/",
+ "saml_idp_initiated_sso_url_name": "sales-post"
+ }
+ },
+ {
+ "name": "http://localhost:8082/sales-post-sig/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/sales-post-sig",
+ "redirectUris": [
+ "http://localhost:8082/sales-post-sig/*"
+ ],
+ "attributes": {
+ "saml_assertion_consumer_url_post": "http://localhost:8082/sales-post-sig/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/sales-post-sig/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/sales-post-sig/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/sales-post-sig/",
+ "saml.server.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA256",
+ "saml.client.signature": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/sales-post-sig-transient/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/sales-post-sig-transient",
+ "adminUrl": "http://localhost:8082/sales-post-sig-transient",
+ "redirectUris": [
+ "http://localhost:8082/sales-post-sig-transient/*"
+ ],
+ "attributes": {
+ "saml_assertion_consumer_url_post": "http://localhost:8082/sales-post-sig-transient/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/sales-post-sig-transient/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/sales-post-sig-transient/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/sales-post-sig-transient/",
+ "saml.server.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA256",
+ "saml.client.signature": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/sales-post-sig-persistent/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/sales-post-sig-persistent",
+ "redirectUris": [
+ "http://localhost:8082/sales-post-sig-persistent/*"
+ ],
+ "attributes": {
+ "saml_assertion_consumer_url_post": "http://localhost:8082/sales-post-sig-persistent/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/sales-post-sig-persistent/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/sales-post-sig-persistent/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/sales-post-sig-persistent/",
+ "saml.server.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA256",
+ "saml.client.signature": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/sales-post-sig-email/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/sales-post-sig-email",
+ "adminUrl": "http://localhost:8082/sales-post-sig-email",
+ "redirectUris": [
+ "http://localhost:8082/sales-post-sig-email/*"
+ ],
+ "attributes": {
+ "saml_force_name_id_format": "true",
+ "saml_name_id_format": "email",
+ "saml_assertion_consumer_url_post": "http://localhost:8082/sales-post-sig-email/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/sales-post-sig-email/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/sales-post-sig-email/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/sales-post-sig-email/",
+ "saml.server.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA256",
+ "saml.client.signature": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/bad-realm-sales-post-sig/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/bad-realm-sales-post-sig/",
+ "adminUrl": "http://localhost:8082/bad-realm-sales-post-sig/",
+ "redirectUris": [
+ "http://localhost:8082/bad-realm-sales-post-sig/*"
+ ],
+ "attributes": {
+ "saml.server.signature": "true",
+ "saml.client.signature": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/bad-client-sales-post-sig/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/bad-client-sales-post-sig/",
+ "adminUrl": "http://localhost:8082/bad-client-sales-post-sig/",
+ "redirectUris": [
+ "http://localhost:8082/bad-client-sales-post-sig/*"
+ ],
+ "attributes": {
+ "saml.server.signature": "true",
+ "saml.client.signature": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/sales-post-enc/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/sales-post-enc",
+ "redirectUris": [
+ "http://localhost:8082/sales-post-enc/*"
+ ],
+ "attributes": {
+ "saml_assertion_consumer_url_post": "http://localhost:8082/sales-post-enc/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/sales-post-enc/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/sales-post-enc/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/sales-post-enc/",
+ "saml.server.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA512",
+ "saml.client.signature": "true",
+ "saml.encrypt": "true",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g==",
+ "saml.encryption.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g=="
+ }
+ },
+ {
+ "name": "http://localhost:8082/employee-sig/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/employee-sig",
+ "redirectUris": [
+ "http://localhost:8082/employee-sig/*"
+ ],
+ "adminUrl": "http://localhost:8082/employee-sig/",
+ "attributes": {
+ "saml.server.signature": "true",
+ "saml.client.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA256",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
+ }
+ },
+ {
+ "name": "http://localhost:8082/employee/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/employee/",
+ "redirectUris": [
+ "http://localhost:8082/employee/*"
+ ],
+ "adminUrl": "http://localhost:8082/employee/",
+ "attributes": {
+ "saml.authnstatement": "true"
+ },
+ "protocolMappers": [
+ {
+ "name": "email",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "email",
+ "friendly.name": "email",
+ "attribute.name": "urn:oid:1.2.840.113549.1.9.1",
+ "attribute.nameformat": "URI Reference"
+ }
+ },
+ {
+ "name": "phone",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "phone",
+ "attribute.name": "phone",
+ "attribute.nameformat": "Basic"
+ }
+ },
+ {
+ "name": "role-list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "attribute.name": "Role",
+ "attribute.nameformat": "Basic",
+ "single": "false"
+ }
+ }
+ ]
+ },
+ {
+ "name": "http://localhost:8082/employee2/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8082/employee2/",
+ "redirectUris": [
+ "http://localhost:8082/employee2/*"
+ ],
+ "adminUrl": "http://localhost:8082/employee2/",
+ "attributes": {
+ "saml.authnstatement": "true"
+ },
+ "protocolMappers": [
+ {
+ "name": "email",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "email",
+ "friendly.name": "email",
+ "attribute.name": "urn:oid:1.2.840.113549.1.9.1",
+ "attribute.nameformat": "URI Reference"
+ }
+ },
+ {
+ "name": "phone",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "phone",
+ "attribute.name": "phone",
+ "attribute.nameformat": "Basic"
+ }
+ },
+ {
+ "name": "role-list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "attribute.name": "Role",
+ "attribute.nameformat": "Basic",
+ "single": "false"
+ }
+ }
+ ]
+ },
+ {
+ "name": "http://localhost:8082/employee-sig-front/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "frontchannelLogout": true,
+ "baseUrl": "http://localhost:8082/employee-sig-front/",
+ "redirectUris": [
+ "http://localhost:8082/employee-sig-front/*"
+ ],
+ "attributes": {
+ "saml_assertion_consumer_url_post": "http://localhost:8082/employee-sig-front/",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8082/employee-sig-front/",
+ "saml_single_logout_service_url_post": "http://localhost:8082/employee-sig-front/",
+ "saml_single_logout_service_url_redirect": "http://localhost:8082/employee-sig-front/",
+ "saml.server.signature": "true",
+ "saml.client.signature": "true",
+ "saml.signature.algorithm": "RSA_SHA1",
+ "saml.authnstatement": "true",
+ "saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
+ }
+ }
+ ],
+ "roles" : {
+ "realm" : [
+ {
+ "name": "manager",
+ "description": "Have Manager privileges"
+ },
+ {
+ "name": "user",
+ "description": "Have User privileges"
+ }
+ ],
+ "application" : {
+ "http://localhost:8082/employee/" : [
+ {
+ "name": "employee",
+ "description": "Have Employee privileges"
+ }
+ ],
+ "http://localhost:8082/employee2/" : [
+ {
+ "name": "employee",
+ "description": "Have Employee privileges"
+ }
+ ]
+ }
+ }
+}