keycloak-uncached

Changes

Details

diff --git a/core/src/main/java/org/keycloak/KeycloakSecurityContext.java b/core/src/main/java/org/keycloak/KeycloakSecurityContext.java
index 830a34e..ec5706f 100755
--- a/core/src/main/java/org/keycloak/KeycloakSecurityContext.java
+++ b/core/src/main/java/org/keycloak/KeycloakSecurityContext.java
@@ -50,7 +50,7 @@ public class KeycloakSecurityContext implements Serializable {
 
     public String getRealm() {
         // Assumption that issuer contains realm name
-        return token.getIssuer();
+        return token.getIssuer().substring(token.getIssuer().lastIndexOf('/') + 1);
     }
 
     // SERIALIZATION
diff --git a/core/src/main/java/org/keycloak/RSATokenVerifier.java b/core/src/main/java/org/keycloak/RSATokenVerifier.java
index da23ff9..e2f5f2b 100755
--- a/core/src/main/java/org/keycloak/RSATokenVerifier.java
+++ b/core/src/main/java/org/keycloak/RSATokenVerifier.java
@@ -12,11 +12,11 @@ import java.security.PublicKey;
  * @version $Revision: 1 $
  */
 public class RSATokenVerifier {
-    public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realm) throws VerificationException {
-        return verifyToken(tokenString, realmKey, realm, true);
+    public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl) throws VerificationException {
+        return verifyToken(tokenString, realmKey, realmUrl, true);
     }
 
-    public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realm, boolean checkActive) throws VerificationException {
+    public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl, boolean checkActive) throws VerificationException {
         JWSInput input = null;
         try {
             input = new JWSInput(tokenString);
@@ -35,7 +35,7 @@ public class RSATokenVerifier {
         if (user == null) {
             throw new VerificationException("Token user was null.");
         }
-        if (!realm.equals(token.getIssuer())) {
+        if (!realmUrl.equals(token.getIssuer())) {
             throw new VerificationException("Token audience doesn't match domain.");
 
         }
diff --git a/core/src/test/java/org/keycloak/RSAVerifierTest.java b/core/src/test/java/org/keycloak/RSAVerifierTest.java
index cb39c6f..5382866 100755
--- a/core/src/test/java/org/keycloak/RSAVerifierTest.java
+++ b/core/src/test/java/org/keycloak/RSAVerifierTest.java
@@ -72,7 +72,7 @@ public class RSAVerifierTest {
 
         token = new AccessToken();
         token.subject("CN=Client")
-                .issuer("domain")
+                .issuer("http://localhost:8080/auth/realm")
                 .addAccess("service").addRole("admin");
     }
 
@@ -102,7 +102,7 @@ public class RSAVerifierTest {
     }
 
     private AccessToken verifySkeletonKeyToken(String encoded) throws VerificationException {
-        return RSATokenVerifier.verifyToken(encoded, idpPair.getPublic(), "domain");
+        return RSATokenVerifier.verifyToken(encoded, idpPair.getPublic(), "http://localhost:8080/auth/realm");
     }
 
    /*
diff --git a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
index 268cddd..789b944 100755
--- a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
+++ b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
@@ -104,7 +104,7 @@ public class SkeletonKeyTokenTest {
     private AccessToken createSimpleToken() {
         AccessToken token = new AccessToken();
         token.id("111");
-        token.issuer("acme");
+        token.issuer("http://localhost:8080/auth/acme");
         token.addAccess("foo").addRole("admin");
         token.addAccess("bar").addRole("user");
         return token;
diff --git a/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index 58b6b02..a12fd9f 100755
--- a/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -80,6 +80,30 @@
     <section>
         <title>Version specific migration</title>
         <section>
+            <title>Migrating from 1.1.0.Final to 1.2.0.Beta1</title>
+            <simplesect>
+                <title><literal>iss</literal> in access and id tokens</title>
+                <para>
+                    The value of <literal>iss</literal> claim in access and id tokens have changed from <literal>realm name</literal>
+                    to <literal>realm url</literal>. This is required by OpenID Connect specification. If you're using our adapters
+                    there's no change required, other than if you've been using bearer-only without specifying <literal>auth-server-url</literal>
+                    you have to add it now. If you're using another library (or RSATokenVerifier) you need to make the corresponding
+                    changes when verifying <literal>iss</literal>.
+                </para>
+            </simplesect>
+            <simplesect>
+                <title>OpenID Connect endpoints</title>
+                <para>
+                    To comply with OpenID Connect specification the authentication and token endpoints have been changed
+                    to having a single authentication endpoint and a single token endpoint. As per-spec <literal>response_type</literal>
+                    and <literal>grant_type</literal> parameters are used to select the required flow. The old endpoints (<literal>/realms/{realm}/protocols/openid-connect/login</literal>,
+                    <literal>/realms/{realm}/protocols/openid-connect/grants/access</literal>, <literal>/realms/{realm}/protocols/openid-connect/refresh</literal>,
+                    <literal>/realms/{realm}/protocols/openid-connect/access/codes)</literal> are now deprecated and will be removed
+                    in a future version.
+                </para>
+            </simplesect>
+        </section>
+        <section>
             <title>Migrating from 1.1.0.Beta2 to 1.1.0.Final</title>
             <itemizedlist>
                 <listitem>
diff --git a/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json
index cba5c8d..cb93854 100755
--- a/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "database-service",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "/auth",
   "bearer-only" : true,
   "ssl-required" : "external"
 }
diff --git a/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java b/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
index ff3237b..bf8212b 100755
--- a/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
+++ b/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
@@ -52,7 +52,7 @@ public class ProtectedServlet extends HttpServlet {
         PrintWriter writer = resp.getWriter();
 
         writer.write("Realm: ");
-        writer.write(principal.getKeycloakSecurityContext().getIdToken().getIssuer());
+        writer.write(principal.getKeycloakSecurityContext().getRealm());
 
         writer.write("<br/>User: ");
         writer.write(principal.getKeycloakSecurityContext().getIdToken().getPreferredUsername());
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java
index 81b1d42..a1a68df 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java
@@ -64,7 +64,7 @@ public class BearerTokenRequestAuthenticator {
     
     protected AuthOutcome authenticateToken(HttpFacade exchange, String tokenString) {
         try {
-            token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+            token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
         } catch (VerificationException e) {
             log.error("Failed to verify token", e);
             challenge = challengeResponse(exchange, "invalid_token", e.getMessage());
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java
index 31bbe0a..526756d 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java
@@ -54,7 +54,7 @@ public class CookieTokenStore {
 
         try {
             // Skip check if token is active now. It's supposed to be done later by the caller
-            AccessToken accessToken = RSATokenVerifier.verifyToken(accessTokenString, deployment.getRealmKey(), deployment.getRealm(), false);
+            AccessToken accessToken = RSATokenVerifier.verifyToken(accessTokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl(), false);
             IDToken idToken;
             if (idTokenString != null && idTokenString.length() > 0) {
                 JWSInput input = new JWSInput(idTokenString);
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java
index a5b56fe..5b6c55d 100644
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java
@@ -173,7 +173,7 @@ public abstract class AbstractKeycloakLoginModule implements LoginModule {
 
 
     protected Auth bearerAuth(String tokenString) throws VerificationException {
-        AccessToken token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+        AccessToken token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
 
         boolean verifyCaller;
         if (deployment.isUseResourceRoleMappings()) {
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
index bd2012f..68688e6 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
@@ -311,7 +311,7 @@ public class OAuthRequestAuthenticator {
         refreshToken = tokenResponse.getRefreshToken();
         idTokenString = tokenResponse.getIdToken();
         try {
-            token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+            token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
             if (idTokenString != null) {
                 JWSInput input = new JWSInput(idTokenString);
                 try {
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java
index 8c0dc91..342ee35 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java
@@ -107,7 +107,7 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext 
         String tokenString = response.getToken();
         AccessToken token = null;
         try {
-            token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+            token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
             log.debug("Token Verification succeeded!");
         } catch (VerificationException e) {
             log.error("failed verification of token");
diff --git a/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java b/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
index e69f6c8..cc2aeb1 100644
--- a/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
+++ b/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
@@ -193,7 +193,7 @@ public class KeycloakInstalled {
         refreshToken = tokenResponse.getRefreshToken();
         idTokenString = tokenResponse.getIdToken();
 
-        token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+        token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
         if (idTokenString != null) {
             JWSInput input = new JWSInput(idTokenString);
             try {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
index dd06346..66197b7 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
@@ -223,6 +223,7 @@ public class AuthorizationEndpoint {
         clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
         clientSession.setNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM, responseType);
         clientSession.setNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUriParam);
+        clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
 
         if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
         if (scope != null) clientSession.setNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
index d796f8f..bd211e4 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
@@ -29,6 +29,7 @@ import org.keycloak.services.ErrorResponseException;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.ClientSessionCode;
 import org.keycloak.services.resources.Cors;
+import org.keycloak.services.resources.flows.Urls;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.OPTIONS;
@@ -319,6 +320,7 @@ public class TokenEndpoint {
 
         ClientSessionModel clientSession = sessions.createClientSession(realm, client);
         clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
+        clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
 
         TokenManager.attachClientSession(userSession, clientSession);
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
index 1e6fc26..b41e972 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
@@ -39,6 +39,7 @@ import org.keycloak.services.managers.AppAuthManager;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.EventsManager;
 import org.keycloak.services.resources.Cors;
+import org.keycloak.services.resources.flows.Urls;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.FormParam;
@@ -52,6 +53,7 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -67,6 +69,9 @@ public class UserInfoEndpoint {
     private HttpResponse response;
 
     @Context
+    private UriInfo uriInfo;
+
+    @Context
     private KeycloakSession session;
 
     @Context
@@ -114,7 +119,7 @@ public class UserInfoEndpoint {
 
         AccessToken token = null;
         try {
-            token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
+            token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
         } catch (Exception e) {
             throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Token invalid", Status.FORBIDDEN);
         }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java
index 8dad6fd..31499d1 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java
@@ -15,6 +15,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.services.ErrorResponseException;
+import org.keycloak.services.resources.flows.Urls;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -68,7 +69,7 @@ public class ValidateTokenEndpoint {
         event.event(EventType.VALIDATE_ACCESS_TOKEN);
         AccessToken token = null;
         try {
-            token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
+            token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
         } catch (Exception e) {
             Map<String, String> err = new HashMap<String, String>();
             err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 022b6ac..5815037 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -59,6 +59,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
     public static final String PROMPT_PARAM = "prompt";
     public static final String LOGIN_HINT_PARAM = "login_hint";
     public static final String LOGOUT_REDIRECT_URI = "OIDC_LOGOUT_REDIRECT_URI";
+    public static final String ISSUER = "iss";
 
     private static final Logger log = Logger.getLogger(OIDCLoginProtocol.class);
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 01e244c..e21d091 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -314,7 +314,7 @@ public class TokenManager {
         token.audience(client.getClientId());
         token.issuedNow();
         token.issuedFor(client.getClientId());
-        token.issuer(realm.getName());
+        token.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER));
         if (session != null) {
             token.setSessionState(session.getId());
         }
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index bdc583a..f8b9bb2 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -32,6 +32,7 @@ import org.keycloak.services.resources.IdentityBrokerService;
 import org.keycloak.services.resources.LoginActionsService;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.flows.Flows;
+import org.keycloak.services.resources.flows.Urls;
 import org.keycloak.services.util.CookieHelper;
 import org.keycloak.services.validation.Validation;
 import org.keycloak.util.Time;
@@ -192,12 +193,12 @@ public class AuthenticationManager {
     }
 
 
-    public static AccessToken createIdentityToken(RealmModel realm, UserModel user, UserSessionModel session) {
+    public static AccessToken createIdentityToken(RealmModel realm, UserModel user, UserSessionModel session, String issuer) {
         AccessToken token = new AccessToken();
         token.id(KeycloakModelUtils.generateId());
         token.issuedNow();
         token.subject(user.getId());
-        token.issuer(realm.getName());
+        token.issuer(issuer);
         if (session != null) {
             token.setSessionState(session.getId());
         }
@@ -209,7 +210,8 @@ public class AuthenticationManager {
 
     public static void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo, ClientConnection connection) {
         String cookiePath = getIdentityCookiePath(realm, uriInfo);
-        AccessToken identityToken = createIdentityToken(realm, user, session);
+        String issuer = Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName());
+        AccessToken identityToken = createIdentityToken(realm, user, session, issuer);
         String encoded = encodeToken(realm, identityToken);
         boolean secureOnly = realm.getSslRequired().isRequired(connection);
         int maxAge = NewCookie.DEFAULT_MAX_AGE;
@@ -443,7 +445,7 @@ public class AuthenticationManager {
 
     protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) {
         try {
-            AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
+            AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), checkActive);
             if (checkActive) {
                 if (!token.isActive() || token.getIssuedAt() < realm.getNotBefore()) {
                     logger.debug("identity cookie expired");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index 8368fc3..4ecdbab 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -140,7 +140,7 @@ public class AdminRoot {
         } catch (IOException e) {
             throw new UnauthorizedException("Bearer token format error");
         }
-        String realmName = token.getIssuer();
+        String realmName = token.getIssuer().substring(token.getIssuer().lastIndexOf('/') + 1);
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = realmManager.getRealmByName(realmName);
         if (realm == null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index a214f62..bb3b078 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -158,6 +158,10 @@ public class Urls {
         return requiredActionsBase(baseUri).path(LoginActionsService.class, "usernameReminder");
     }
 
+    public static String realmIssuer(URI baseUri, String realmId) {
+        return realmBase(baseUri).path("{realm}").build(realmId).toString();
+    }
+
     private static UriBuilder realmBase(URI baseUri) {
         return UriBuilder.fromUri(baseUri).path(RealmsResource.class);
     }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index c8371bd..ce61d33 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -1,471 +1,471 @@
-/*
- * 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.account;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.events.Details;
-import org.keycloak.events.Event;
-import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.AccountService;
-import org.keycloak.services.resources.RealmsResource;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.pages.AccountLogPage;
-import org.keycloak.testsuite.pages.AccountPasswordPage;
-import org.keycloak.testsuite.pages.AccountSessionsPage;
-import org.keycloak.testsuite.pages.AccountTotpPage;
-import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
-import org.keycloak.testsuite.pages.AppPage;
-import org.keycloak.testsuite.pages.AppPage.RequestType;
-import org.keycloak.testsuite.pages.ErrorPage;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.pages.RegisterPage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebDriver;
-
-import javax.ws.rs.core.UriBuilder;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
- */
-public class AccountTest {
-
-    @ClassRule
-    public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
-        @Override
-        public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
-
-            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
-
-            UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
-            user2.setEnabled(true);
-            for (String r : accountApp.getDefaultRoles()) {
-                user2.deleteRoleMapping(accountApp.getRole(r));
-            }
-            UserCredentialModel creds = new UserCredentialModel();
-            creds.setType(CredentialRepresentation.PASSWORD);
-            creds.setValue("password");
-            user2.updateCredential(creds);
-        }
-    });
-
-    private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8081/auth");
-    private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
-    public static String ACCOUNT_REDIRECT = AccountService.loginRedirectUrl(BASE.clone()).build("test").toString();
-
-    @Rule
-    public AssertEvents events = new AssertEvents(keycloakRule);
-
-    @Rule
-    public WebRule webRule = new WebRule(this);
-
-    @WebResource
-    protected WebDriver driver;
-
-    @WebResource
-    protected OAuthClient oauth;
-
-    @WebResource
-    protected AppPage appPage;
-
-    @WebResource
-    protected LoginPage loginPage;
-
-    @WebResource
-    protected RegisterPage registerPage;
-
-    @WebResource
-    protected AccountPasswordPage changePasswordPage;
-
-    @WebResource
-    protected AccountUpdateProfilePage profilePage;
-
-    @WebResource
-    protected AccountTotpPage totpPage;
-
-    @WebResource
-    protected AccountLogPage logPage;
-
-    @WebResource
-    protected AccountSessionsPage sessionsPage;
-
-    @WebResource
-    protected ErrorPage errorPage;
-
-    private TimeBasedOTP totp = new TimeBasedOTP();
-    private String userId;
-
-    @Before
-    public void before() {
-        oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
-        userId = keycloakRule.getUser("test", "test-user@localhost").getId();
-    }
-
-    @After
-    public void after() {
-        keycloakRule.update(new KeycloakSetup() {
-            @Override
-            public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
-                UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
-
-                UserCredentialModel cred = new UserCredentialModel();
-                cred.setType(CredentialRepresentation.PASSWORD);
-                cred.setValue("password");
-
-                user.updateCredential(cred);
-            }
-        });
-    }
-
-    //@Test @Ignore
-    public void runit() throws Exception {
-        Thread.sleep(10000000);
-    }
-
-    @Test
-    public void returnToAppFromQueryParam() {
-        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
-        loginPage.login("test-user@localhost", "password");
-        Assert.assertTrue(profilePage.isCurrent());
-        profilePage.backToApplication();
-
-        Assert.assertTrue(appPage.isCurrent());
-
-        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
-        Assert.assertTrue(profilePage.isCurrent());
-        profilePage.backToApplication();
-
-        Assert.assertTrue(appPage.isCurrent());
-        Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
-
-        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
-        Assert.assertTrue(profilePage.isCurrent());
-
-        driver.findElement(By.linkText("Authenticator")).click();
-        Assert.assertTrue(totpPage.isCurrent());
-
-        driver.findElement(By.linkText("Account")).click();
-        Assert.assertTrue(profilePage.isCurrent());
-
-        profilePage.backToApplication();
-
-        Assert.assertTrue(appPage.isCurrent());
-
-        events.clear();
-    }
-
-    @Test
-    public void changePassword() {
-        changePasswordPage.open();
-        loginPage.login("test-user@localhost", "password");
-
-        String sessionId = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent().getSessionId();
-
-        changePasswordPage.changePassword("", "new-password", "new-password");
-
-        Assert.assertEquals("Please specify password.", profilePage.getError());
-
-        changePasswordPage.changePassword("password", "new-password", "new-password2");
-
-        Assert.assertEquals("Password confirmation doesn't match.", profilePage.getError());
-
-        changePasswordPage.changePassword("password", "new-password", "new-password");
-
-        Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
-
-        events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
-
-        changePasswordPage.logout();
-
-        events.expectLogout(sessionId).detail(Details.REDIRECT_URI, changePasswordPage.getPath()).assertEvent();
-
-        loginPage.open();
-        loginPage.login("test-user@localhost", "password");
-
-        Assert.assertEquals("Invalid username or password.", loginPage.getError());
-
-        events.expectLogin().session((String) null).error("invalid_user_credentials").assertEvent();
-
-        loginPage.open();
-        loginPage.login("test-user@localhost", "new-password");
-
-        Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
-
-        events.expectLogin().assertEvent();
-    }
-
-    @Test
-    public void changePasswordWithPasswordPolicy() {
-        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
-            @Override
-            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.setPasswordPolicy(new PasswordPolicy("length"));
-            }
-        });
-
-        try {
-            changePasswordPage.open();
-            loginPage.login("test-user@localhost", "password");
-
-
-            events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
-
-            changePasswordPage.changePassword("", "new", "new");
-
-            Assert.assertEquals("Please specify password.", profilePage.getError());
-
-            changePasswordPage.changePassword("password", "new-password", "new-password");
-
-            Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
-
-            events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
-        } finally {
-            keycloakRule.update(new KeycloakRule.KeycloakSetup() {
-                @Override
-                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.setPasswordPolicy(new PasswordPolicy(null));
-                }
-            });
-        }
-    }
-
-    @Test
-    public void changeProfile() {
-        profilePage.open();
-        loginPage.login("test-user@localhost", "password");
-
-        events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
-
-        Assert.assertEquals("Tom", profilePage.getFirstName());
-        Assert.assertEquals("Brady", profilePage.getLastName());
-        Assert.assertEquals("test-user@localhost", profilePage.getEmail());
-
-        // All fields are required, so there should be an error when something is missing.
-        profilePage.updateProfile("", "New last", "new@email.com");
-
-        Assert.assertEquals("Please specify first name.", profilePage.getError());
-        Assert.assertEquals("", profilePage.getFirstName());
-        Assert.assertEquals("New last", profilePage.getLastName());
-        Assert.assertEquals("new@email.com", profilePage.getEmail());
-
-        events.assertEmpty();
-
-        profilePage.updateProfile("New first", "", "new@email.com");
-
-        Assert.assertEquals("Please specify last name.", profilePage.getError());
-        Assert.assertEquals("New first", profilePage.getFirstName());
-        Assert.assertEquals("", profilePage.getLastName());
-        Assert.assertEquals("new@email.com", profilePage.getEmail());
-
-        events.assertEmpty();
-
-        profilePage.updateProfile("New first", "New last", "");
-
-        Assert.assertEquals("Please specify email.", profilePage.getError());
-        Assert.assertEquals("New first", profilePage.getFirstName());
-        Assert.assertEquals("New last", profilePage.getLastName());
-        Assert.assertEquals("", profilePage.getEmail());
-
-        events.assertEmpty();
-
-        profilePage.clickCancel();
-
-        Assert.assertEquals("Tom", profilePage.getFirstName());
-        Assert.assertEquals("Brady", profilePage.getLastName());
-        Assert.assertEquals("test-user@localhost", profilePage.getEmail());
-
-        events.assertEmpty();
-
-        profilePage.updateProfile("New first", "New last", "new@email.com");
-
-        Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
-        Assert.assertEquals("New first", profilePage.getFirstName());
-        Assert.assertEquals("New last", profilePage.getLastName());
-        Assert.assertEquals("new@email.com", profilePage.getEmail());
-
-        events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
-        events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
-    }
-
-    @Test
-    public void setupTotp() {
-        totpPage.open();
-        loginPage.login("test-user@localhost", "password");
-
-        events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
-
-        Assert.assertTrue(totpPage.isCurrent());
-
-        Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
-
-        // Error with false code
-        totpPage.configure(totp.generate(totpPage.getTotpSecret() + "123"));
-
-        Assert.assertEquals("Invalid authenticator code.", profilePage.getError());
-
-        totpPage.configure(totp.generate(totpPage.getTotpSecret()));
-
-        Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
-
-        events.expectAccount(EventType.UPDATE_TOTP).assertEvent();
-
-        Assert.assertTrue(driver.getPageSource().contains("pficon-delete"));
-
-        totpPage.removeTotp();
-
-        events.expectAccount(EventType.REMOVE_TOTP).assertEvent();
-    }
-
-    @Test
-    public void changeProfileNoAccess() throws Exception {
-        profilePage.open();
-        loginPage.login("test-user-no-access@localhost", "password");
-
-        events.expectLogin().client("account").user(keycloakRule.getUser("test", "test-user-no-access@localhost").getId())
-                .detail(Details.USERNAME, "test-user-no-access@localhost")
-                .detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
-
-        Assert.assertTrue(errorPage.isCurrent());
-        Assert.assertEquals("No access", errorPage.getError());
-    }
-
-    @Test
-    public void viewLog() {
-        keycloakRule.update(new KeycloakSetup() {
-            @Override
-            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.setEventsEnabled(true);
-            }
-        });
-
-        try {
-            List<Event> expectedEvents = new LinkedList<Event>();
-
-            loginPage.open();
-            loginPage.clickRegister();
-
-            registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
-
-            expectedEvents.add(events.poll());
-            expectedEvents.add(events.poll());
-
-            profilePage.open();
-            profilePage.updateProfile("view", "log2", "view-log@localhost");
-
-            expectedEvents.add(events.poll());
-
-            logPage.open();
-
-            Assert.assertTrue(logPage.isCurrent());
-
-            List<List<String>> actualEvents = logPage.getEvents();
-
-            Assert.assertEquals(expectedEvents.size(), actualEvents.size());
-
-            for (Event e : expectedEvents) {
-                boolean match = false;
-                for (List<String> a : logPage.getEvents()) {
-                    if (e.getType().toString().replace('_', ' ').toLowerCase().equals(a.get(1)) &&
-                            e.getIpAddress().equals(a.get(2)) &&
-                            e.getClientId().equals(a.get(3))) {
-                        match = true;
-                        break;
-                    }
-                }
-                if (!match) {
-                    Assert.fail("Event not found " + e.getType());
-                }
-            }
-        } finally {
-            keycloakRule.update(new KeycloakSetup() {
-                @Override
-                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.setEventsEnabled(false);
-                }
-            });
-        }
-    }
-
-    @Test
-    public void sessions() {
-        loginPage.open();
-        loginPage.clickRegister();
-
-        registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
-
-        Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
-        String userId = registerEvent.getUserId();
-
-        events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
-
-        sessionsPage.open();
-
-        Assert.assertTrue(sessionsPage.isCurrent());
-
-        List<List<String>> sessions = sessionsPage.getSessions();
-        Assert.assertEquals(1, sessions.size());
-        Assert.assertEquals("127.0.0.1", sessions.get(0).get(0));
-
-        // Create second session
-        WebDriver driver2 = WebRule.createWebDriver();
-        try {
-            OAuthClient oauth2 = new OAuthClient(driver2);
-            oauth2.state("mystate");
-            oauth2.doLogin("view-sessions", "password");
-
-            Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
-
-            sessionsPage.open();
-            sessions = sessionsPage.getSessions();
-            Assert.assertEquals(2, sessions.size());
-
-            sessionsPage.logoutAll();
-
-            events.expectLogout(registerEvent.getSessionId());
-            events.expectLogout(login2Event.getSessionId());
-        } finally {
-            driver2.close();
-        }
-    }
-
-}
+/*
+ * 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.account;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.events.Details;
+import org.keycloak.events.Event;
+import org.keycloak.events.EventType;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.TimeBasedOTP;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.AccountService;
+import org.keycloak.services.resources.RealmsResource;
+import org.keycloak.testsuite.AssertEvents;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AccountLogPage;
+import org.keycloak.testsuite.pages.AccountPasswordPage;
+import org.keycloak.testsuite.pages.AccountSessionsPage;
+import org.keycloak.testsuite.pages.AccountTotpPage;
+import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.AppPage.RequestType;
+import org.keycloak.testsuite.pages.ErrorPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+
+import javax.ws.rs.core.UriBuilder;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AccountTest {
+
+    @ClassRule
+    public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
+        @Override
+        public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
+
+            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
+
+            UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
+            user2.setEnabled(true);
+            for (String r : accountApp.getDefaultRoles()) {
+                user2.deleteRoleMapping(accountApp.getRole(r));
+            }
+            UserCredentialModel creds = new UserCredentialModel();
+            creds.setType(CredentialRepresentation.PASSWORD);
+            creds.setValue("password");
+            user2.updateCredential(creds);
+        }
+    });
+
+    private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8081/auth");
+    private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
+    public static String ACCOUNT_REDIRECT = AccountService.loginRedirectUrl(BASE.clone()).build("test").toString();
+
+    @Rule
+    public AssertEvents events = new AssertEvents(keycloakRule);
+
+    @Rule
+    public WebRule webRule = new WebRule(this);
+
+    @WebResource
+    protected WebDriver driver;
+
+    @WebResource
+    protected OAuthClient oauth;
+
+    @WebResource
+    protected AppPage appPage;
+
+    @WebResource
+    protected LoginPage loginPage;
+
+    @WebResource
+    protected RegisterPage registerPage;
+
+    @WebResource
+    protected AccountPasswordPage changePasswordPage;
+
+    @WebResource
+    protected AccountUpdateProfilePage profilePage;
+
+    @WebResource
+    protected AccountTotpPage totpPage;
+
+    @WebResource
+    protected AccountLogPage logPage;
+
+    @WebResource
+    protected AccountSessionsPage sessionsPage;
+
+    @WebResource
+    protected ErrorPage errorPage;
+
+    private TimeBasedOTP totp = new TimeBasedOTP();
+    private String userId;
+
+    @Before
+    public void before() {
+        oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
+        userId = keycloakRule.getUser("test", "test-user@localhost").getId();
+    }
+
+    @After
+    public void after() {
+        keycloakRule.update(new KeycloakSetup() {
+            @Override
+            public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
+                UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
+
+                UserCredentialModel cred = new UserCredentialModel();
+                cred.setType(CredentialRepresentation.PASSWORD);
+                cred.setValue("password");
+
+                user.updateCredential(cred);
+            }
+        });
+    }
+
+    //@Test @Ignore
+    public void runit() throws Exception {
+        Thread.sleep(10000000);
+    }
+
+    @Test
+    public void returnToAppFromQueryParam() {
+        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
+        loginPage.login("test-user@localhost", "password");
+        Assert.assertTrue(profilePage.isCurrent());
+        profilePage.backToApplication();
+
+        Assert.assertTrue(appPage.isCurrent());
+
+        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
+        Assert.assertTrue(profilePage.isCurrent());
+        profilePage.backToApplication();
+
+        Assert.assertTrue(appPage.isCurrent());
+        Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
+
+        driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
+        Assert.assertTrue(profilePage.isCurrent());
+
+        driver.findElement(By.linkText("Authenticator")).click();
+        Assert.assertTrue(totpPage.isCurrent());
+
+        driver.findElement(By.linkText("Account")).click();
+        Assert.assertTrue(profilePage.isCurrent());
+
+        profilePage.backToApplication();
+
+        Assert.assertTrue(appPage.isCurrent());
+
+        events.clear();
+    }
+
+    @Test
+    public void changePassword() {
+        changePasswordPage.open();
+        loginPage.login("test-user@localhost", "password");
+
+        String sessionId = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent().getSessionId();
+
+        changePasswordPage.changePassword("", "new-password", "new-password");
+
+        Assert.assertEquals("Please specify password.", profilePage.getError());
+
+        changePasswordPage.changePassword("password", "new-password", "new-password2");
+
+        Assert.assertEquals("Password confirmation doesn't match.", profilePage.getError());
+
+        changePasswordPage.changePassword("password", "new-password", "new-password");
+
+        Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
+
+        events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
+
+        changePasswordPage.logout();
+
+        events.expectLogout(sessionId).detail(Details.REDIRECT_URI, changePasswordPage.getPath()).assertEvent();
+
+        loginPage.open();
+        loginPage.login("test-user@localhost", "password");
+
+        Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+        events.expectLogin().session((String) null).error("invalid_user_credentials").assertEvent();
+
+        loginPage.open();
+        loginPage.login("test-user@localhost", "new-password");
+
+        Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+        events.expectLogin().assertEvent();
+    }
+
+    @Test
+    public void changePasswordWithPasswordPolicy() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                appRealm.setPasswordPolicy(new PasswordPolicy("length"));
+            }
+        });
+
+        try {
+            changePasswordPage.open();
+            loginPage.login("test-user@localhost", "password");
+
+
+            events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
+
+            changePasswordPage.changePassword("", "new", "new");
+
+            Assert.assertEquals("Please specify password.", profilePage.getError());
+
+            changePasswordPage.changePassword("password", "new-password", "new-password");
+
+            Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
+
+            events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
+        } finally {
+            keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+                @Override
+                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                    appRealm.setPasswordPolicy(new PasswordPolicy(null));
+                }
+            });
+        }
+    }
+
+    @Test
+    public void changeProfile() {
+        profilePage.open();
+        loginPage.login("test-user@localhost", "password");
+
+        events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
+
+        Assert.assertEquals("Tom", profilePage.getFirstName());
+        Assert.assertEquals("Brady", profilePage.getLastName());
+        Assert.assertEquals("test-user@localhost", profilePage.getEmail());
+
+        // All fields are required, so there should be an error when something is missing.
+        profilePage.updateProfile("", "New last", "new@email.com");
+
+        Assert.assertEquals("Please specify first name.", profilePage.getError());
+        Assert.assertEquals("", profilePage.getFirstName());
+        Assert.assertEquals("New last", profilePage.getLastName());
+        Assert.assertEquals("new@email.com", profilePage.getEmail());
+
+        events.assertEmpty();
+
+        profilePage.updateProfile("New first", "", "new@email.com");
+
+        Assert.assertEquals("Please specify last name.", profilePage.getError());
+        Assert.assertEquals("New first", profilePage.getFirstName());
+        Assert.assertEquals("", profilePage.getLastName());
+        Assert.assertEquals("new@email.com", profilePage.getEmail());
+
+        events.assertEmpty();
+
+        profilePage.updateProfile("New first", "New last", "");
+
+        Assert.assertEquals("Please specify email.", profilePage.getError());
+        Assert.assertEquals("New first", profilePage.getFirstName());
+        Assert.assertEquals("New last", profilePage.getLastName());
+        Assert.assertEquals("", profilePage.getEmail());
+
+        events.assertEmpty();
+
+        profilePage.clickCancel();
+
+        Assert.assertEquals("Tom", profilePage.getFirstName());
+        Assert.assertEquals("Brady", profilePage.getLastName());
+        Assert.assertEquals("test-user@localhost", profilePage.getEmail());
+
+        events.assertEmpty();
+
+        profilePage.updateProfile("New first", "New last", "new@email.com");
+
+        Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
+        Assert.assertEquals("New first", profilePage.getFirstName());
+        Assert.assertEquals("New last", profilePage.getLastName());
+        Assert.assertEquals("new@email.com", profilePage.getEmail());
+
+        events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
+        events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
+    }
+
+    @Test
+    public void setupTotp() {
+        totpPage.open();
+        loginPage.login("test-user@localhost", "password");
+
+        events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
+
+        Assert.assertTrue(totpPage.isCurrent());
+
+        Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
+
+        // Error with false code
+        totpPage.configure(totp.generate(totpPage.getTotpSecret() + "123"));
+
+        Assert.assertEquals("Invalid authenticator code.", profilePage.getError());
+
+        totpPage.configure(totp.generate(totpPage.getTotpSecret()));
+
+        Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
+
+        events.expectAccount(EventType.UPDATE_TOTP).assertEvent();
+
+        Assert.assertTrue(driver.getPageSource().contains("pficon-delete"));
+
+        totpPage.removeTotp();
+
+        events.expectAccount(EventType.REMOVE_TOTP).assertEvent();
+    }
+
+    @Test
+    public void changeProfileNoAccess() throws Exception {
+        profilePage.open();
+        loginPage.login("test-user-no-access@localhost", "password");
+
+        events.expectLogin().client("account").user(keycloakRule.getUser("test", "test-user-no-access@localhost").getId())
+                .detail(Details.USERNAME, "test-user-no-access@localhost")
+                .detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
+
+        Assert.assertTrue(errorPage.isCurrent());
+        Assert.assertEquals("No access", errorPage.getError());
+    }
+
+    @Test
+    public void viewLog() {
+        keycloakRule.update(new KeycloakSetup() {
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                appRealm.setEventsEnabled(true);
+            }
+        });
+
+        try {
+            List<Event> expectedEvents = new LinkedList<Event>();
+
+            loginPage.open();
+            loginPage.clickRegister();
+
+            registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
+
+            expectedEvents.add(events.poll());
+            expectedEvents.add(events.poll());
+
+            profilePage.open();
+            profilePage.updateProfile("view", "log2", "view-log@localhost");
+
+            expectedEvents.add(events.poll());
+
+            logPage.open();
+
+            Assert.assertTrue(logPage.isCurrent());
+
+            List<List<String>> actualEvents = logPage.getEvents();
+
+            Assert.assertEquals(expectedEvents.size(), actualEvents.size());
+
+            for (Event e : expectedEvents) {
+                boolean match = false;
+                for (List<String> a : logPage.getEvents()) {
+                    if (e.getType().toString().replace('_', ' ').toLowerCase().equals(a.get(1)) &&
+                            e.getIpAddress().equals(a.get(2)) &&
+                            e.getClientId().equals(a.get(3))) {
+                        match = true;
+                        break;
+                    }
+                }
+                if (!match) {
+                    Assert.fail("Event not found " + e.getType());
+                }
+            }
+        } finally {
+            keycloakRule.update(new KeycloakSetup() {
+                @Override
+                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                    appRealm.setEventsEnabled(false);
+                }
+            });
+        }
+    }
+
+    @Test
+    public void sessions() {
+        loginPage.open();
+        loginPage.clickRegister();
+
+        registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
+
+        Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
+        String userId = registerEvent.getUserId();
+
+        events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
+
+        sessionsPage.open();
+
+        Assert.assertTrue(sessionsPage.isCurrent());
+
+        List<List<String>> sessions = sessionsPage.getSessions();
+        Assert.assertEquals(1, sessions.size());
+        Assert.assertEquals("127.0.0.1", sessions.get(0).get(0));
+
+        // Create second session
+        WebDriver driver2 = WebRule.createWebDriver();
+        try {
+            OAuthClient oauth2 = new OAuthClient(driver2);
+            oauth2.state("mystate");
+            oauth2.doLogin("view-sessions", "password");
+
+            Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
+
+            sessionsPage.open();
+            sessions = sessionsPage.getSessions();
+            Assert.assertEquals(2, sessions.size());
+
+            sessionsPage.logoutAll();
+
+            events.expectLogout(registerEvent.getSessionId());
+            events.expectLogout(login2Event.getSessionId());
+        } finally {
+            driver2.close();
+        }
+    }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index b7d39fc..45e007a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -30,11 +30,13 @@ import org.keycloak.Version;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.constants.AdapterConstants;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 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.OIDCLoginProtocolService;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.representations.AccessToken;
@@ -140,8 +142,10 @@ public class AdapterTestStrategy extends ExternalResource {
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
-            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
-            AccessToken token = tm.createClientAccessToken(session, TokenManager.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+            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);
+            AccessToken token = tm.createClientAccessToken(session, TokenManager.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
             return tm.encodeToken(adminRealm, token);
         } finally {
             keycloakRule.stopSession(session, true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
index 56f8b8f..4e300b6 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
@@ -27,11 +27,13 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 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.OIDCLoginProtocolService;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.representations.AccessToken;
@@ -86,8 +88,10 @@ public class RelativeUriAdapterTest {
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
-            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "user", null, "form", false, null, null);
-            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+            ClientSessionModel clientSession = session.sessions().createClientSession(realm, adminConsole);
+            clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
+            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "user", null, "form", false);
+            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
             adminToken = tm.encodeToken(adminRealm, token);
 
         }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
index 873bbff..c6871a2 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -26,11 +26,13 @@ import org.junit.ClassRule;
 import org.junit.Test;
 import org.keycloak.Config;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 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.representations.AccessToken;
 import org.keycloak.representations.idm.ApplicationRepresentation;
@@ -78,8 +80,10 @@ public class AdminAPITest {
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
-            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
-            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+            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);
+            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
             return tm.encodeToken(adminRealm, token);
         } finally {
             keycloakRule.stopSession(session, true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index 9319661..80d0310 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -225,7 +225,7 @@ public class OAuthClient {
 
     public AccessToken verifyToken(String token) {
         try {
-            return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
+            return RSATokenVerifier.verifyToken(token, realmPublicKey, baseUrl + "/realms/" + realm);
         } catch (VerificationException e) {
             throw new RuntimeException("Failed to verify token", e);
         }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
index 91970e6..c354fc3 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
@@ -1,474 +1,478 @@
-package org.keycloak.testsuite.saml;
-
-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.models.ApplicationModel;
-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.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.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 org.picketlink.common.constants.JBossSAMLURIConstants;
-import org.picketlink.identity.federation.api.saml.v2.response.SAML2Response;
-import org.picketlink.identity.federation.core.saml.v2.constants.X500SAMLProfileConstants;
-import org.picketlink.identity.federation.saml.v2.assertion.AssertionType;
-import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
-import org.picketlink.identity.federation.saml.v2.assertion.AttributeType;
-import org.picketlink.identity.federation.saml.v2.protocol.ResponseType;
-import org.picketlink.identity.federation.web.util.PostBindingUtil;
-
-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.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-public class SamlBindingTest {
-
-    @ClassRule
-    public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
-        @Override
-        public void initWars() {
-             ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
-
-            initializeSamlSecuredWar("/saml/simple-post", "/sales-post",  "post.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig",  "post-sig.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email",  "post-sig-email.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient",  "post-sig-transient.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent",  "post-sig-persistent.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata",  "post-metadata.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-get", "/employee-sig",  "employee-sig.war", classLoader);
-            //initializeSamlSecuredWar("/saml/simple-get", "/employee",  "employee.war", classLoader);
-            initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front",  "employee-sig-front.war", classLoader);
-            initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig",  "bad-client-post-sig.war", classLoader);
-            initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig",  "bad-realm-post-sig.war", classLoader);
-            initializeSamlSecuredWar("/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 "/saml/testsaml.json";
-        }
-    };
-
-    public static class SamlSPFacade extends HttpServlet {
-        public static String samlResponse;
-
-        @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);
-                resp.setHeader("Location", "http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
-                return;
-            }
-            System.out.println("received response");
-            samlResponse = req.getParameter("SAMLResponse");
-        }
-    }
-
-    @Rule
-    public WebRule webRule = new WebRule(this);
-    @WebResource
-    protected WebDriver driver;
-    @WebResource
-    protected LoginPage loginPage;
-
-    //@Test
-    public void runit() throws Exception {
-        Thread.sleep(10000000);
-    }
-
-    protected void checkLoggedOut(String mainUrl) {
-        String pageSource = driver.getPageSource();
-        System.out.println("*** logout pagesouce ***");
-        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 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 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 testAttributes() 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 assertions sent.  This is because Picketlink, AFAICT, does not give you any way to get access to
-        // the assertion.
-
-        {
-            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.assertNotNull(SamlSPFacade.samlResponse);
-            SAML2Response saml2Response = new SAML2Response();
-            byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
-            ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
-            Assert.assertTrue(rt.getAssertions().size() == 1);
-            AssertionType assertion = rt.getAssertions().get(0).getAssertion();
-
-            // test attributes and roles
-
-            boolean email = false;
-            boolean phone = false;
-            boolean userRole = false;
-            boolean managerRole = false;
-            for (AttributeStatementType statement : assertion.getAttributeStatements()) {
-                for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
-                    AttributeType attr = choice.getAttribute();
-                    if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attr.getFriendlyName())) {
-                        Assert.assertEquals(X500SAMLProfileConstants.EMAIL.get(), attr.getName());
-                        Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get(), attr.getNameFormat());
-                        Assert.assertEquals(attr.getAttributeValue().get(0), "bburke@redhat.com");
-                        email = true;
-                    } else if (attr.getName().equals("phone")) {
-                        Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
-                        Assert.assertEquals(attr.getAttributeValue().get(0), "617");
-                        phone = true;
-                    } else if (attr.getName().equals("Role")) {
-                        if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
-                        if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
-                    }
-                }
-
-            }
-
-            Assert.assertTrue(email);
-            Assert.assertTrue(phone);
-            Assert.assertTrue(userRole);
-            Assert.assertTrue(managerRole);
-        }
-
-        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
-            @Override
-            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                ApplicationModel app = appRealm.getApplicationByName("http://localhost:8081/employee/");
-                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 <<<<<<<<");
-
-        {
-            SamlSPFacade.samlResponse = null;
-            driver.navigate().to("http://localhost:8081/employee/");
-            System.out.println(driver.getCurrentUrl());
-            Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
-            Assert.assertNotNull(SamlSPFacade.samlResponse);
-            SAML2Response saml2Response = new SAML2Response();
-            byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
-            ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
-            Assert.assertTrue(rt.getAssertions().size() == 1);
-            AssertionType assertion = rt.getAssertions().get(0).getAssertion();
-
-            // test attributes and roles
-
-            boolean userRole = false;
-            boolean managerRole = false;
-            boolean single = false;
-            boolean hardcodedRole = false;
-            boolean hardcodedAttribute = false;
-            boolean peeOn = false;
-            for (AttributeStatementType statement : assertion.getAttributeStatements()) {
-                for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
-                    AttributeType attr = choice.getAttribute();
-                    if (attr.getName().equals("memberOf")) {
-                        if (single) Assert.fail("too many role attributes");
-                        single = true;
-                        for (Object value : attr.getAttributeValue()) {
-                            if (value.equals("el-jefe")) managerRole = true;
-                            if (value.equals("user")) userRole = true;
-                            if (value.equals("hardcoded-role")) hardcodedRole = true;
-                            if (value.equals("pee-on")) peeOn = true;
-                        }
-                    } else if (attr.getName().equals("hardcoded-attribute")) {
-                        hardcodedAttribute = true;
-                        Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
-                    }
-                }
-
-            }
-
-            Assert.assertTrue(single);
-            Assert.assertTrue(hardcodedAttribute);
-            Assert.assertTrue(hardcodedRole);
-            Assert.assertTrue(peeOn);
-            Assert.assertTrue(userRole);
-            Assert.assertTrue(managerRole);
-        }
-    }
-
-    @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/");
-        Assert.assertTrue(driver.getCurrentUrl().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());
-            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
-            TokenManager tm = new TokenManager();
-            UserModel admin = session.users().getUserByUsername("admin", adminRealm);
-            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
-            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
-            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("/saml/sp-metadata.xml");
-        Assert.assertNotNull(is);
-        formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
-
-        WebTarget upload = adminRealms.path("demo/application-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();
-    }
-
-
-}
+package org.keycloak.testsuite.saml;
+
+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.models.ApplicationModel;
+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.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 org.picketlink.common.constants.JBossSAMLURIConstants;
+import org.picketlink.identity.federation.api.saml.v2.response.SAML2Response;
+import org.picketlink.identity.federation.core.saml.v2.constants.X500SAMLProfileConstants;
+import org.picketlink.identity.federation.saml.v2.assertion.AssertionType;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeType;
+import org.picketlink.identity.federation.saml.v2.protocol.ResponseType;
+import org.picketlink.identity.federation.web.util.PostBindingUtil;
+
+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.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SamlBindingTest {
+
+    @ClassRule
+    public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
+        @Override
+        public void initWars() {
+             ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
+
+            initializeSamlSecuredWar("/saml/simple-post", "/sales-post",  "post.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig",  "post-sig.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email",  "post-sig-email.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient",  "post-sig-transient.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent",  "post-sig-persistent.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata",  "post-metadata.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-get", "/employee-sig",  "employee-sig.war", classLoader);
+            //initializeSamlSecuredWar("/saml/simple-get", "/employee",  "employee.war", classLoader);
+            initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front",  "employee-sig-front.war", classLoader);
+            initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig",  "bad-client-post-sig.war", classLoader);
+            initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig",  "bad-realm-post-sig.war", classLoader);
+            initializeSamlSecuredWar("/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 "/saml/testsaml.json";
+        }
+    };
+
+    public static class SamlSPFacade extends HttpServlet {
+        public static String samlResponse;
+
+        @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);
+                resp.setHeader("Location", "http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
+                return;
+            }
+            System.out.println("received response");
+            samlResponse = req.getParameter("SAMLResponse");
+        }
+    }
+
+    @Rule
+    public WebRule webRule = new WebRule(this);
+    @WebResource
+    protected WebDriver driver;
+    @WebResource
+    protected LoginPage loginPage;
+
+    //@Test
+    public void runit() throws Exception {
+        Thread.sleep(10000000);
+    }
+
+    protected void checkLoggedOut(String mainUrl) {
+        String pageSource = driver.getPageSource();
+        System.out.println("*** logout pagesouce ***");
+        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 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 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 testAttributes() 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 assertions sent.  This is because Picketlink, AFAICT, does not give you any way to get access to
+        // the assertion.
+
+        {
+            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.assertNotNull(SamlSPFacade.samlResponse);
+            SAML2Response saml2Response = new SAML2Response();
+            byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
+            ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
+            Assert.assertTrue(rt.getAssertions().size() == 1);
+            AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+
+            // test attributes and roles
+
+            boolean email = false;
+            boolean phone = false;
+            boolean userRole = false;
+            boolean managerRole = false;
+            for (AttributeStatementType statement : assertion.getAttributeStatements()) {
+                for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
+                    AttributeType attr = choice.getAttribute();
+                    if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attr.getFriendlyName())) {
+                        Assert.assertEquals(X500SAMLProfileConstants.EMAIL.get(), attr.getName());
+                        Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get(), attr.getNameFormat());
+                        Assert.assertEquals(attr.getAttributeValue().get(0), "bburke@redhat.com");
+                        email = true;
+                    } else if (attr.getName().equals("phone")) {
+                        Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
+                        Assert.assertEquals(attr.getAttributeValue().get(0), "617");
+                        phone = true;
+                    } else if (attr.getName().equals("Role")) {
+                        if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
+                        if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
+                    }
+                }
+
+            }
+
+            Assert.assertTrue(email);
+            Assert.assertTrue(phone);
+            Assert.assertTrue(userRole);
+            Assert.assertTrue(managerRole);
+        }
+
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                ApplicationModel app = appRealm.getApplicationByName("http://localhost:8081/employee/");
+                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 <<<<<<<<");
+
+        {
+            SamlSPFacade.samlResponse = null;
+            driver.navigate().to("http://localhost:8081/employee/");
+            System.out.println(driver.getCurrentUrl());
+            Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+            Assert.assertNotNull(SamlSPFacade.samlResponse);
+            SAML2Response saml2Response = new SAML2Response();
+            byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
+            ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
+            Assert.assertTrue(rt.getAssertions().size() == 1);
+            AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+
+            // test attributes and roles
+
+            boolean userRole = false;
+            boolean managerRole = false;
+            boolean single = false;
+            boolean hardcodedRole = false;
+            boolean hardcodedAttribute = false;
+            boolean peeOn = false;
+            for (AttributeStatementType statement : assertion.getAttributeStatements()) {
+                for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
+                    AttributeType attr = choice.getAttribute();
+                    if (attr.getName().equals("memberOf")) {
+                        if (single) Assert.fail("too many role attributes");
+                        single = true;
+                        for (Object value : attr.getAttributeValue()) {
+                            if (value.equals("el-jefe")) managerRole = true;
+                            if (value.equals("user")) userRole = true;
+                            if (value.equals("hardcoded-role")) hardcodedRole = true;
+                            if (value.equals("pee-on")) peeOn = true;
+                        }
+                    } else if (attr.getName().equals("hardcoded-attribute")) {
+                        hardcodedAttribute = true;
+                        Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
+                    }
+                }
+
+            }
+
+            Assert.assertTrue(single);
+            Assert.assertTrue(hardcodedAttribute);
+            Assert.assertTrue(hardcodedRole);
+            Assert.assertTrue(peeOn);
+            Assert.assertTrue(userRole);
+            Assert.assertTrue(managerRole);
+        }
+    }
+
+    @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/");
+        Assert.assertTrue(driver.getCurrentUrl().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());
+            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+            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);
+            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, 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("/saml/sp-metadata.xml");
+        Assert.assertNotNull(is);
+        formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
+
+        WebTarget upload = adminRealms.path("demo/application-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/resources/adapter-test/customer-db-keycloak.json b/testsuite/integration/src/test/resources/adapter-test/customer-db-keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/integration/src/test/resources/adapter-test/customer-db-keycloak.json
+++ b/testsuite/integration/src/test/resources/adapter-test/customer-db-keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java
index d5d2379..a57ee22 100755
--- a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java
@@ -166,7 +166,7 @@ public class OAuthClient {
 
     public AccessToken verifyToken(String token) {
         try {
-            return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
+            return RSATokenVerifier.verifyToken(token, realmPublicKey, baseUrl + "/" + realm);
         } catch (VerificationException e) {
             throw new RuntimeException("Failed to verify token", e);
         }
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..912fef2 100755
--- a/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,8 +2,8 @@
   "realm" : "demo",
   "resource" : "customer-db",
   "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+  "auth-server-url": "http://localhost:8081/auth",
   "ssl-required" : "external",
   "bearer-only" : true,
   "enable-cors" : true
-
-}
+}
\ No newline at end of file