keycloak-uncached

merge

11/10/2014 8:09:00 PM

Changes

Details

diff --git a/core/src/main/java/org/keycloak/constants/GenericConstants.java b/core/src/main/java/org/keycloak/constants/GenericConstants.java
new file mode 100644
index 0000000..a5a8f83
--- /dev/null
+++ b/core/src/main/java/org/keycloak/constants/GenericConstants.java
@@ -0,0 +1,10 @@
+package org.keycloak.constants;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class GenericConstants {
+
+    public static final String PROTOCOL_CLASSPATH = "classpath:";
+
+}
diff --git a/core/src/main/java/org/keycloak/util/KeystoreUtil.java b/core/src/main/java/org/keycloak/util/KeystoreUtil.java
index 6c715a2..ba264c0 100755
--- a/core/src/main/java/org/keycloak/util/KeystoreUtil.java
+++ b/core/src/main/java/org/keycloak/util/KeystoreUtil.java
@@ -5,18 +5,18 @@ import java.io.FileInputStream;
 import java.io.InputStream;
 import java.security.KeyStore;
 
+import org.keycloak.constants.GenericConstants;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class KeystoreUtil {
 
-    private static final String PROTOCOL_CLASSPATH = "classpath:";
-
     public static KeyStore loadKeyStore(String filename, String password) throws Exception {
         KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
-        InputStream trustStream = (filename.startsWith(PROTOCOL_CLASSPATH))
-                ?KeystoreUtil.class.getResourceAsStream(filename.replace(PROTOCOL_CLASSPATH, ""))
+        InputStream trustStream = (filename.startsWith(GenericConstants.PROTOCOL_CLASSPATH))
+                ?KeystoreUtil.class.getResourceAsStream(filename.replace(GenericConstants.PROTOCOL_CLASSPATH, ""))
                 :new FileInputStream(new File(filename));
         trustStore.load(trustStream, password.toCharArray());
         trustStream.close();
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 973bc6e..332b270 100755
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -30,6 +30,8 @@
         <module>tomcat7-adapter-zip</module>
         <module>eap6-adapter-zip</module>
         <module>wildfly-adapter-zip</module>
+        <module>jetty91-adapter-zip</module>
+        <module>jetty92-adapter-zip</module>
         <module>examples-docs-zip</module>
         <module>theme-template-zip</module>
         <module>war-zip</module>
diff --git a/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java b/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java
index caa9ed6..9f7ec37 100755
--- a/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java
+++ b/examples/demo-template/admin-access-app/src/main/java/org/keycloak/example/AdminClient.java
@@ -9,7 +9,7 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.message.BasicNameValuePair;
 import org.keycloak.OAuth2Constants;
-import org.keycloak.ServiceUrlConstants;
+import org.keycloak.constants.ServiceUrlConstants;
 import org.keycloak.adapters.HttpClientBuilder;
 import org.keycloak.representations.AccessTokenResponse;
 import org.keycloak.representations.idm.RoleRepresentation;
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java
index f04f144..fcbf1fe 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java
@@ -2,6 +2,7 @@ package org.keycloak.adapters;
 
 import org.jboss.logging.Logger;
 import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.representations.AccessToken;
 
 import java.io.IOException;
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 8a35572..31bbe0a 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
@@ -6,6 +6,7 @@ import org.jboss.logging.Logger;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.RSATokenVerifier;
 import org.keycloak.VerificationException;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.IDToken;
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
index fdd295e..4b13bd8 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
@@ -2,7 +2,7 @@ package org.keycloak.adapters;
 
 import org.apache.http.client.HttpClient;
 import org.jboss.logging.Logger;
-import org.keycloak.ServiceUrlConstants;
+import org.keycloak.constants.ServiceUrlConstants;
 import org.keycloak.enums.RelativeUrlsUsed;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.enums.TokenStore;
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java
index 099697f..aff38dc 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java
@@ -2,6 +2,7 @@ package org.keycloak.adapters;
 
 import org.jboss.logging.Logger;
 import org.keycloak.Version;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.crypto.RSAProvider;
 import org.keycloak.representations.adapters.action.AdminAction;
@@ -166,7 +167,7 @@ public class PreAuthActionsHandler {
         if (!facade.getRequest().isSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
             log.warn("SSL is required for adapter admin action");
             facade.getResponse().sendError(403, "ssl required");
-
+            return null;
         }
         String token = StreamUtil.readString(facade.getRequest().getInputStream());
         if (token == null) {
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java
index f4a3142..741edc7 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java
@@ -8,6 +8,7 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.message.BasicNameValuePair;
 import org.keycloak.OAuth2Constants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.representations.AccessTokenResponse;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.util.BasicAuthHelper;
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
index e63d43d..c2d42c1 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
@@ -13,7 +13,7 @@ import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.deploy.LoginConfig;
 import org.jboss.logging.Logger;
 import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.adapters.AdapterDeploymentContext;
 import org.keycloak.adapters.AdapterTokenStore;
 import org.keycloak.adapters.AuthChallenge;
diff --git a/integration/jaxrs-oauth-client/pom.xml b/integration/jaxrs-oauth-client/pom.xml
index ef9bc1b..a167f99 100755
--- a/integration/jaxrs-oauth-client/pom.xml
+++ b/integration/jaxrs-oauth-client/pom.xml
@@ -15,11 +15,6 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.jboss.logging</groupId>
-            <artifactId>jboss-logging</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
             <groupId>org.jboss.resteasy</groupId>
             <artifactId>jaxrs-api</artifactId>
             <version>${resteasy.version.latest}</version>
@@ -44,6 +39,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-adapter-core</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.codehaus.jackson</groupId>
             <artifactId>jackson-core-asl</artifactId>
             <scope>provided</scope>
@@ -69,6 +70,13 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.3.0</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
old mode 100755
new mode 100644
index e7ffc5b..f0bce71
--- a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
@@ -1,115 +1,14 @@
-package org.keycloak.jaxrs;
-
-import org.jboss.logging.Logger;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.keycloak.KeycloakPrincipal;
-import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.RSATokenVerifier;
-import org.keycloak.VerificationException;
-import org.keycloak.representations.AccessToken;
-
-import javax.annotation.Priority;
-import javax.ws.rs.Priorities;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.SecurityContext;
-import java.io.IOException;
-import java.security.Principal;
-import java.security.PublicKey;
-
-/**
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-@Priority(Priorities.AUTHENTICATION)
-public class JaxrsBearerTokenFilter implements ContainerRequestFilter {
-    private static Logger log = Logger.getLogger(JaxrsBearerTokenFilter.class);
-    protected String realm;
-    protected PublicKey realmPublicKey;
-    protected String resourceName;
-
-    public JaxrsBearerTokenFilter(String realm, PublicKey realmPublicKey, String resourceName) {
-        this.realm = realm;
-        this.realmPublicKey = realmPublicKey;
-        this.resourceName = resourceName;
-    }
-
-    protected void challengeResponse(ContainerRequestContext request, String error, String description) {
-        StringBuilder header = new StringBuilder("Bearer realm=\"");
-        header.append(realm).append("\"");
-        if (error != null) {
-            header.append(", error=\"").append(error).append("\"");
-        }
-        if (description != null) {
-            header.append(", error_description=\"").append(description).append("\"");
-        }
-        request.abortWith(Response.status(Response.Status.UNAUTHORIZED).header(HttpHeaders.WWW_AUTHENTICATE, header.toString()).build());
-        return;
-    }
-
-    @Context
-    protected SecurityContext securityContext;
-
-    @Override
-    public void filter(ContainerRequestContext request) throws IOException {
-        String authHeader = request.getHeaderString(HttpHeaders.AUTHORIZATION);
-        if (authHeader == null) {
-            challengeResponse(request, null, null);
-            return;
-        }
-
-        String[] split = authHeader.trim().split("\\s+");
-        if (split == null || split.length != 2) challengeResponse(request, null, null);
-        if (!split[0].equalsIgnoreCase("Bearer")) challengeResponse(request, null, null);
-
-
-        String tokenString = split[1];
-
-
-        try {
-            AccessToken token = RSATokenVerifier.verifyToken(tokenString, realmPublicKey, realm);
-            KeycloakSecurityContext skSession = new KeycloakSecurityContext(tokenString, token, null, null);
-            ResteasyProviderFactory.pushContext(KeycloakSecurityContext.class, skSession);
-
-            final KeycloakPrincipal<KeycloakSecurityContext> principal = new KeycloakPrincipal<KeycloakSecurityContext>(token.getSubject(), skSession);
-            final boolean isSecure = securityContext.isSecure();
-            final AccessToken.Access access;
-            if (resourceName != null) {
-                access = token.getResourceAccess(resourceName);
-            } else {
-                access = token.getRealmAccess();
-            }
-            SecurityContext ctx = new SecurityContext() {
-                @Override
-                public Principal getUserPrincipal() {
-                    return principal;
-                }
-
-                @Override
-                public boolean isUserInRole(String role) {
-                    if (access == null) return false;
-                    if (access.getRoles() == null) return false;
-                    return access.getRoles().contains(role);
-                }
-
-                @Override
-                public boolean isSecure() {
-                    return isSecure;
-                }
-
-                @Override
-                public String getAuthenticationScheme() {
-                    return "OAUTH_BEARER";
-                }
-            };
-            request.setSecurityContext(ctx);
-        } catch (VerificationException e) {
-            log.error("Failed to verify token", e);
-            challengeResponse(request, "invalid_token", e.getMessage());
-        }
-    }
-
-}
+package org.keycloak.jaxrs;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@PreMatching
+@Priority(Priorities.AUTHENTICATION)
+public interface JaxrsBearerTokenFilter extends ContainerRequestFilter {
+}
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilterImpl.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilterImpl.java
new file mode 100755
index 0000000..33795c2
--- /dev/null
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilterImpl.java
@@ -0,0 +1,289 @@
+package org.keycloak.jaxrs;
+
+import org.keycloak.KeycloakPrincipal;
+import org.keycloak.adapters.AdapterDeploymentContext;
+import org.keycloak.adapters.AdapterUtils;
+import org.keycloak.adapters.AuthChallenge;
+import org.keycloak.adapters.AuthOutcome;
+import org.keycloak.adapters.AuthenticatedActionsHandler;
+import org.keycloak.adapters.BearerTokenRequestAuthenticator;
+import org.keycloak.adapters.KeycloakConfigResolver;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.KeycloakDeploymentBuilder;
+import org.keycloak.adapters.NodesRegistrationManagement;
+import org.keycloak.adapters.PreAuthActionsHandler;
+import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
+import org.keycloak.adapters.UserSessionManagement;
+import org.keycloak.constants.GenericConstants;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@PreMatching
+@Priority(Priorities.AUTHENTICATION)
+public class JaxrsBearerTokenFilterImpl implements JaxrsBearerTokenFilter {
+
+    private final static Logger log = Logger.getLogger("" + JaxrsBearerTokenFilterImpl.class);
+
+    private String keycloakConfigFile;
+    private String keycloakConfigResolverClass;
+    protected volatile boolean started;
+
+    protected AdapterDeploymentContext deploymentContext;
+
+    // TODO: Should also somehow handle stop lifecycle for de-registration
+    protected NodesRegistrationManagement nodesRegistrationManagement;
+    protected UserSessionManagement userSessionManagement = new EmptyUserSessionManagement();
+
+    public void setKeycloakConfigFile(String configFile) {
+        this.keycloakConfigFile = configFile;
+        attemptStart();
+    }
+
+    public String getKeycloakConfigFile() {
+        return this.keycloakConfigFile;
+    }
+
+    public String getKeycloakConfigResolverClass() {
+        return keycloakConfigResolverClass;
+    }
+
+    public void setKeycloakConfigResolverClass(String keycloakConfigResolverClass) {
+        this.keycloakConfigResolverClass = keycloakConfigResolverClass;
+        attemptStart();
+    }
+
+    // INITIALIZATION AND STARTUP
+
+    protected void attemptStart() {
+        if (started) {
+            throw new IllegalStateException("Filter already started. Make sure to specify just keycloakConfigResolver or keycloakConfigFile but not both");
+        }
+
+        if (isInitialized()) {
+            start();
+        } else {
+            log.fine("Not yet initialized");
+        }
+    }
+
+    protected boolean isInitialized() {
+        return this.keycloakConfigFile != null || this.keycloakConfigResolverClass != null;
+    }
+
+    protected void start() {
+        if (started) {
+            throw new IllegalStateException("Filter already started. Make sure to specify just keycloakConfigResolver or keycloakConfigFile but not both");
+        }
+
+        if (keycloakConfigResolverClass != null) {
+            Class<? extends KeycloakConfigResolver> resolverClass = loadResolverClass();
+
+            try {
+                KeycloakConfigResolver resolver = resolverClass.newInstance();
+                log.info("Using " + resolver + " to resolve Keycloak configuration on a per-request basis.");
+                this.deploymentContext = new AdapterDeploymentContext(resolver);
+            } catch (Exception e) {
+                throw new RuntimeException("Unable to instantiate resolver " + resolverClass);
+            }
+        } else {
+            if (keycloakConfigFile == null) {
+                throw new IllegalArgumentException("You need to specify either keycloakConfigResolverClass or keycloakConfigFile in configuration");
+            }
+            InputStream is = loadKeycloakConfigFile();
+            KeycloakDeployment kd = KeycloakDeploymentBuilder.build(is);
+            deploymentContext = new AdapterDeploymentContext(kd);
+            log.info("Keycloak is using a per-deployment configuration loaded from: " + keycloakConfigFile);
+        }
+
+        nodesRegistrationManagement = new NodesRegistrationManagement();
+        started = true;
+    }
+
+    protected Class<? extends KeycloakConfigResolver> loadResolverClass() {
+        try {
+            return (Class<? extends KeycloakConfigResolver>)getClass().getClassLoader().loadClass(keycloakConfigResolverClass);
+        } catch (ClassNotFoundException cnfe) {
+            // Fallback to tccl
+            try {
+                return (Class<? extends KeycloakConfigResolver>)Thread.currentThread().getContextClassLoader().loadClass(keycloakConfigResolverClass);
+            } catch (ClassNotFoundException cnfe2) {
+                throw new RuntimeException("Unable to find resolver class: " + keycloakConfigResolverClass);
+            }
+        }
+    }
+
+    protected InputStream loadKeycloakConfigFile() {
+        if (keycloakConfigFile.startsWith(GenericConstants.PROTOCOL_CLASSPATH)) {
+            String classPathLocation = keycloakConfigFile.replace(GenericConstants.PROTOCOL_CLASSPATH, "");
+            log.fine("Loading config from classpath on location: " + classPathLocation);
+            // Try current class classloader first
+            InputStream is = getClass().getClassLoader().getResourceAsStream(classPathLocation);
+            if (is == null) {
+                is = Thread.currentThread().getContextClassLoader().getResourceAsStream(classPathLocation);
+            }
+
+            if (is != null) {
+                return is;
+            } else {
+                throw new RuntimeException("Unable to find config from classpath: " + keycloakConfigFile);
+            }
+        } else {
+            // Fallback to file
+            try {
+                log.fine("Loading config from file: " + keycloakConfigFile);
+                return new FileInputStream(keycloakConfigFile);
+            } catch (FileNotFoundException fnfe) {
+                log.severe("Config not found on " + keycloakConfigFile);
+                throw new RuntimeException(fnfe);
+            }
+        }
+    }
+
+    // REQUEST HANDLING
+
+    @Override
+    public void filter(ContainerRequestContext request) throws IOException {
+        SecurityContext securityContext = getRequestSecurityContext(request);
+        JaxrsHttpFacade facade = new JaxrsHttpFacade(request, securityContext);
+        if (handlePreauth(facade)) {
+            return;
+        }
+
+        KeycloakDeployment resolvedDeployment = deploymentContext.resolveDeployment(facade);
+
+        nodesRegistrationManagement.tryRegister(resolvedDeployment);
+
+        bearerAuthentication(facade, request, resolvedDeployment);
+    }
+
+    protected boolean handlePreauth(JaxrsHttpFacade facade) {
+        PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deploymentContext, facade);
+        if (handler.handleRequest()) {
+            // Send response now (if not already sent)
+            if (!facade.isResponseFinished()) {
+                facade.getResponse().end();
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    protected void bearerAuthentication(JaxrsHttpFacade facade, ContainerRequestContext request, KeycloakDeployment resolvedDeployment) {
+        BearerTokenRequestAuthenticator bearer = new BearerTokenRequestAuthenticator(resolvedDeployment);
+        AuthOutcome outcome = bearer.authenticate(facade);
+        if (outcome == AuthOutcome.FAILED || outcome == AuthOutcome.NOT_ATTEMPTED) {
+            AuthChallenge challenge = bearer.getChallenge();
+            log.fine("Authentication outcome: " + outcome);
+            boolean challengeSent = challenge.challenge(facade);
+            if (!challengeSent) {
+                // Use some default status code
+                facade.getResponse().setStatus(Response.Status.UNAUTHORIZED.getStatusCode());
+            }
+
+            // Send response now (if not already sent)
+            if (!facade.isResponseFinished()) {
+                facade.getResponse().end();
+            }
+            return;
+        } else {
+            if (verifySslFailed(facade, resolvedDeployment)) {
+                return;
+            }
+        }
+
+        propagateSecurityContext(facade, request, resolvedDeployment, bearer);
+        handleAuthActions(facade, resolvedDeployment);
+    }
+
+    protected void propagateSecurityContext(JaxrsHttpFacade facade, ContainerRequestContext request, KeycloakDeployment resolvedDeployment, BearerTokenRequestAuthenticator bearer) {
+        RefreshableKeycloakSecurityContext skSession = new RefreshableKeycloakSecurityContext(resolvedDeployment, null, bearer.getTokenString(), bearer.getToken(), null, null, null);
+
+        // Not needed to do resteasy specifics as KeycloakSecurityContext can be always retrieved from SecurityContext by typecast SecurityContext.getUserPrincipal to KeycloakPrincipal
+        // ResteasyProviderFactory.pushContext(KeycloakSecurityContext.class, skSession);
+
+        facade.setSecurityContext(skSession);
+        String principalName = AdapterUtils.getPrincipalName(resolvedDeployment, bearer.getToken());
+        final KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = new KeycloakPrincipal<RefreshableKeycloakSecurityContext>(principalName, skSession);
+        SecurityContext anonymousSecurityContext = getRequestSecurityContext(request);
+        final boolean isSecure = anonymousSecurityContext.isSecure();
+        final Set<String> roles = AdapterUtils.getRolesFromSecurityContext(skSession);
+
+        SecurityContext ctx = new SecurityContext() {
+            @Override
+            public Principal getUserPrincipal() {
+                return principal;
+            }
+
+            @Override
+            public boolean isUserInRole(String role) {
+                return roles.contains(role);
+            }
+
+            @Override
+            public boolean isSecure() {
+                return isSecure;
+            }
+
+            @Override
+            public String getAuthenticationScheme() {
+                return "OAUTH_BEARER";
+            }
+        };
+        request.setSecurityContext(ctx);
+    }
+
+    protected boolean verifySslFailed(JaxrsHttpFacade facade, KeycloakDeployment deployment) {
+        if (!facade.getRequest().isSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
+            log.warning("SSL is required to authenticate, but request is not secured");
+            facade.getResponse().sendError(403, "SSL required!");
+            return true;
+        }
+        return false;
+    }
+
+    protected SecurityContext getRequestSecurityContext(ContainerRequestContext request) {
+        return request.getSecurityContext();
+    }
+
+    protected void handleAuthActions(JaxrsHttpFacade facade, KeycloakDeployment deployment) {
+        AuthenticatedActionsHandler authActionsHandler = new AuthenticatedActionsHandler(deployment, facade);
+        if (authActionsHandler.handledRequest()) {
+            // Send response now (if not already sent)
+            if (!facade.isResponseFinished()) {
+                facade.getResponse().end();
+            }
+        }
+    }
+
+    // We don't have any sessions to manage with pure jaxrs filter
+    private static class EmptyUserSessionManagement implements UserSessionManagement {
+
+        @Override
+        public void logoutAll() {
+        }
+
+        @Override
+        public void logoutHttpSessions(List<String> ids) {
+        }
+    }
+
+}
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java
new file mode 100644
index 0000000..f29935d
--- /dev/null
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsHttpFacade.java
@@ -0,0 +1,172 @@
+package org.keycloak.jaxrs;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.cert.X509Certificate;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.SecurityContext;
+
+import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.adapters.HttpFacade;
+import org.keycloak.util.HostUtils;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class JaxrsHttpFacade implements HttpFacade {
+
+    protected final ContainerRequestContext requestContext;
+    protected final SecurityContext securityContext;
+    protected final RequestFacade requestFacade = new RequestFacade();
+    protected final ResponseFacade responseFacade = new ResponseFacade();
+    protected KeycloakSecurityContext keycloakSecurityContext;
+    protected boolean responseFinished;
+
+    public JaxrsHttpFacade(ContainerRequestContext containerRequestContext, SecurityContext securityContext) {
+        this.requestContext = containerRequestContext;
+        this.securityContext = securityContext;
+    }
+
+    protected class RequestFacade implements HttpFacade.Request {
+
+        @Override
+        public String getMethod() {
+            return requestContext.getMethod();
+        }
+
+        @Override
+        public String getURI() {
+            return requestContext.getUriInfo().getRequestUri().toString();
+        }
+
+        @Override
+        public boolean isSecure() {
+            return securityContext.isSecure();
+        }
+
+        @Override
+        public String getQueryParamValue(String param) {
+            MultivaluedMap<String, String> queryParams = requestContext.getUriInfo().getQueryParameters();
+            if (queryParams == null)
+                return null;
+            return queryParams.getFirst(param);
+        }
+
+        @Override
+        public Cookie getCookie(String cookieName) {
+            Map<String, javax.ws.rs.core.Cookie> cookies = requestContext.getCookies();
+            if (cookies == null)
+                return null;
+            javax.ws.rs.core.Cookie cookie = cookies.get(cookieName);
+            if (cookie == null)
+                return null;
+            return new Cookie(cookie.getName(), cookie.getValue(), cookie.getVersion(), cookie.getDomain(), cookie.getPath());
+        }
+
+        @Override
+        public String getHeader(String name) {
+            return requestContext.getHeaderString(name);
+        }
+
+        @Override
+        public List<String> getHeaders(String name) {
+            MultivaluedMap<String, String> headers = requestContext.getHeaders();
+            return (headers == null) ? null : headers.get(name);
+        }
+
+        @Override
+        public InputStream getInputStream() {
+            return requestContext.getEntityStream();
+        }
+
+        @Override
+        public String getRemoteAddr() {
+            // TODO: implement properly
+            return HostUtils.getIpAddress();
+        }
+    }
+
+    protected class ResponseFacade implements HttpFacade.Response {
+
+        private javax.ws.rs.core.Response.ResponseBuilder responseBuilder = javax.ws.rs.core.Response.status(204);
+
+        @Override
+        public void setStatus(int status) {
+            responseBuilder.status(status);
+        }
+
+        @Override
+        public void addHeader(String name, String value) {
+            responseBuilder.header(name, value);
+        }
+
+        @Override
+        public void setHeader(String name, String value) {
+            responseBuilder.header(name, value);
+        }
+
+        @Override
+        public void resetCookie(String name, String path) {
+            // For now doesn't need to be supported
+            throw new IllegalStateException("Not supported yet");
+        }
+
+        @Override
+        public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) {
+            // For now doesn't need to be supported
+            throw new IllegalStateException("Not supported yet");
+        }
+
+        @Override
+        public OutputStream getOutputStream() {
+            // For now doesn't need to be supported
+            throw new IllegalStateException("Not supported yet");
+        }
+
+        @Override
+        public void sendError(int code, String message) {
+            javax.ws.rs.core.Response response = responseBuilder.status(code).entity(message).build();
+            requestContext.abortWith(response);
+            responseFinished = true;
+        }
+
+        @Override
+        public void end() {
+            javax.ws.rs.core.Response response = responseBuilder.build();
+            requestContext.abortWith(response);
+            responseFinished = true;
+        }
+    }
+
+    @Override
+    public KeycloakSecurityContext getSecurityContext() {
+        return keycloakSecurityContext;
+    }
+
+    public void setSecurityContext(KeycloakSecurityContext securityContext) {
+        this.keycloakSecurityContext = securityContext;
+    }
+
+    @Override
+    public Request getRequest() {
+        return requestFacade;
+    }
+
+    @Override
+    public Response getResponse() {
+        return responseFacade;
+    }
+
+    @Override
+    public X509Certificate[] getCertificateChain() {
+        throw new IllegalStateException("Not supported yet");
+    }
+
+    public boolean isResponseFinished() {
+        return responseFinished;
+    }
+}
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
index b453203..6944782 100755
--- a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
@@ -1,6 +1,5 @@
 package org.keycloak.jaxrs;
 
-import org.jboss.logging.Logger;
 import org.keycloak.AbstractOAuthClient;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.representations.AccessTokenResponse;
@@ -18,6 +17,7 @@ import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import java.net.URI;
 import java.util.Map;
+import java.util.logging.Logger;
 
 /**
  * Helper code to obtain oauth access tokens via browser redirects
@@ -26,7 +26,7 @@ import java.util.Map;
  * @version $Revision: 1 $
  */
 public class JaxrsOAuthClient extends AbstractOAuthClient {
-    protected static final Logger logger = Logger.getLogger(JaxrsOAuthClient.class);
+    private final static Logger logger = Logger.getLogger("" + JaxrsOAuthClient.class);
     protected Client client;
 
     /**
@@ -80,8 +80,8 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
         URI url = uriBuilder.build();
 
         NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
-        logger.debug("NewCookie: " + cookie.toString());
-        logger.debug("Oauth Redirect to: " + url);
+        logger.fine("NewCookie: " + cookie.toString());
+        logger.fine("Oauth Redirect to: " + url);
         return Response.status(302)
                 .location(url)
                 .cookie(cookie).build();
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/OsgiJaxrsBearerTokenFilterImpl.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/OsgiJaxrsBearerTokenFilterImpl.java
new file mode 100644
index 0000000..2c2f4b0
--- /dev/null
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/OsgiJaxrsBearerTokenFilterImpl.java
@@ -0,0 +1,78 @@
+package org.keycloak.jaxrs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Logger;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.PreMatching;
+
+import org.keycloak.adapters.KeycloakConfigResolver;
+import org.keycloak.constants.GenericConstants;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Variant of JaxrsBearerTokenFilter, which can be used to properly use resources from current osgi bundle
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@PreMatching
+@Priority(Priorities.AUTHENTICATION)
+public class OsgiJaxrsBearerTokenFilterImpl extends JaxrsBearerTokenFilterImpl {
+
+    private final static Logger log = Logger.getLogger("" + JaxrsBearerTokenFilterImpl.class);
+
+    private BundleContext bundleContext;
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+        attemptStart();
+    }
+
+    @Override
+    protected boolean isInitialized() {
+        return super.isInitialized() && bundleContext != null;
+    }
+
+    @Override
+    protected Class<? extends KeycloakConfigResolver> loadResolverClass() {
+        String resolverClass = getKeycloakConfigResolverClass();
+        try {
+            return (Class<? extends KeycloakConfigResolver>) bundleContext.getBundle().loadClass(resolverClass);
+        } catch (ClassNotFoundException cnfe) {
+            log.warning("Not able to find class from bundleContext. Fallback to current classloader");
+            return super.loadResolverClass();
+        }
+    }
+
+    @Override
+    protected InputStream loadKeycloakConfigFile() {
+        String keycloakConfigFile = getKeycloakConfigFile();
+        if (keycloakConfigFile.startsWith(GenericConstants.PROTOCOL_CLASSPATH)) {
+
+            // Load from classpath of current bundle
+            String classPathLocation = keycloakConfigFile.replace(GenericConstants.PROTOCOL_CLASSPATH, "");
+            log.fine("Loading config from classpath on location: " + classPathLocation);
+
+            URL cfgUrl = bundleContext.getBundle().getResource(classPathLocation);
+            if (cfgUrl == null) {
+                log.warning("Not able to find configFile from bundleContext. Fallback to current classloader");
+                return super.loadKeycloakConfigFile();
+            }
+
+            try {
+                return cfgUrl.openStream();
+            } catch (IOException ioe) {
+                throw new RuntimeException(ioe);
+            }
+        } else {
+            return super.loadKeycloakConfigFile();
+        }
+    }
+}
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java
index e2e2cba..72f0d0f 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/AbstractKeycloakJettyAuthenticator.java
@@ -12,7 +12,6 @@ import org.eclipse.jetty.server.handler.ContextHandler;
 import org.jboss.logging.Logger;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.adapters.AdapterConstants;
 import org.keycloak.adapters.AdapterDeploymentContext;
 import org.keycloak.adapters.AdapterTokenStore;
 import org.keycloak.adapters.AdapterUtils;
@@ -26,6 +25,7 @@ import org.keycloak.adapters.KeycloakDeploymentBuilder;
 import org.keycloak.adapters.NodesRegistrationManagement;
 import org.keycloak.adapters.PreAuthActionsHandler;
 import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.enums.TokenStore;
 import org.keycloak.representations.adapters.config.AdapterConfig;
 
diff --git a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java
index e9013fd..5620636 100755
--- a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java
+++ b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClientBuilder.java
@@ -1,7 +1,7 @@
 package org.keycloak.servlet;
 
 import org.apache.http.client.HttpClient;
-import org.keycloak.ServiceUrlConstants;
+import org.keycloak.constants.ServiceUrlConstants;
 import org.keycloak.adapters.HttpClientBuilder;
 import org.keycloak.enums.RelativeUrlsUsed;
 import org.keycloak.representations.adapters.config.AdapterConfig;
diff --git a/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java b/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java
index d62e9b0..5d0f271 100755
--- a/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java
+++ b/integration/tomcat7/adapter/src/main/java/org/keycloak/adapters/tomcat7/KeycloakAuthenticatorValve.java
@@ -12,7 +12,7 @@ import org.apache.catalina.connector.Response;
 import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.deploy.LoginConfig;
 import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.adapters.AdapterDeploymentContext;
 import org.keycloak.adapters.AdapterTokenStore;
 import org.keycloak.adapters.AuthChallenge;
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
index 9484021..4014a92 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
@@ -32,7 +32,7 @@ import io.undertow.servlet.api.LoginConfig;
 import io.undertow.servlet.api.ServletSessionConfig;
 import io.undertow.servlet.util.ImmediateInstanceHandle;
 import org.jboss.logging.Logger;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.adapters.AdapterDeploymentContext;
 import org.keycloak.adapters.KeycloakDeployment;
 import org.keycloak.adapters.KeycloakDeploymentBuilder;
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java b/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
index 0c60ccb..2c47adb 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OpenIDConnectService.java
@@ -14,7 +14,7 @@ import org.keycloak.Config;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.OAuthErrorException;
 import org.keycloak.RSATokenVerifier;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
@@ -41,7 +41,6 @@ import org.keycloak.services.resources.Cors;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.Urls;
-import org.keycloak.util.Base64Url;
 import org.keycloak.util.BasicAuthHelper;
 import org.keycloak.util.StreamUtil;
 import org.keycloak.util.UriUtils;
diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
index 7760e52..d3fb82a 100755
--- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
@@ -6,7 +6,7 @@ import org.jboss.resteasy.client.ClientRequest;
 import org.jboss.resteasy.client.ClientResponse;
 import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
 import org.keycloak.TokenIdGenerator;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
diff --git a/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java b/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java
index 0ce2793..0fdbc81 100755
--- a/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java
+++ b/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java
@@ -1,6 +1,5 @@
 package org.keycloak.services.resources;
 
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -22,7 +21,7 @@ import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.UnauthorizedException;
 import org.keycloak.ClientConnection;
 import org.keycloak.OAuth2Constants;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index 77252b9..6ca12ba 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -126,6 +126,11 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-jaxrs-oauth-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
             <artifactId>federation-properties-example</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
index e17208d..58d0851 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
@@ -28,7 +28,7 @@ import org.junit.Test;
 import org.keycloak.Config;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.Version;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/CookieTokenStoreAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/CookieTokenStoreAdapterTest.java
index 24b04c9..8218258 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/CookieTokenStoreAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/CookieTokenStoreAdapterTest.java
@@ -8,7 +8,7 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.oidc.OpenIDConnectService;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/Constants.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/Constants.java
index 459f44c..3f009ef 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/Constants.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/Constants.java
@@ -26,6 +26,7 @@ package org.keycloak.testsuite;
  */
 public class Constants {
 
-    public static String AUTH_SERVER_ROOT = "http://localhost:8081/auth";
+    public static String SERVER_ROOT = "http://localhost:8081";
+    public static String AUTH_SERVER_ROOT = SERVER_ROOT + "/auth";
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java
new file mode 100644
index 0000000..936792d
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java
@@ -0,0 +1,345 @@
+package org.keycloak.testsuite.jaxrs;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.jboss.resteasy.client.jaxrs.ResteasyClient;
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.keycloak.OAuth2Constants;
+import org.keycloak.TokenIdGenerator;
+import org.keycloak.adapters.CorsHeaders;
+import org.keycloak.constants.AdapterConstants;
+import org.keycloak.adapters.HttpClientBuilder;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.protocol.oidc.TokenManager;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.Constants;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.keycloak.util.Time;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class JaxrsFilterTest {
+
+    private static final String JAXRS_APP_URL = Constants.SERVER_ROOT + "/jaxrs-simple/res";
+    private static final String JAXRS_APP_PUSN_NOT_BEFORE_URL = Constants.SERVER_ROOT + "/jaxrs-simple/" + AdapterConstants.K_PUSH_NOT_BEFORE;
+
+    public static final String CONFIG_FILE_INIT_PARAM = "config-file";
+
+    @ClassRule
+    public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
+
+        @Override
+        public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+            ApplicationModel app = appRealm.addApplication("jaxrs-app");
+            app.setEnabled(true);
+            RoleModel role = app.addRole("jaxrs-app-user");
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
+            user.grantRole(role);
+
+            JaxrsFilterTest.appRealm = appRealm;
+        }
+    });
+
+    @ClassRule
+    public static ExternalResource clientRule = new ExternalResource() {
+
+        @Override
+        protected void before() throws Throwable {
+            DefaultHttpClient httpClient = (DefaultHttpClient) new HttpClientBuilder().build();
+            ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
+            client = new ResteasyClientBuilder().httpEngine(engine).build();
+        }
+
+        @Override
+        protected void after() {
+            client.close();
+        }
+    };
+
+    private static ResteasyClient client;
+
+    @Rule
+    public WebRule webRule = new WebRule(this);
+
+    @WebResource
+    protected WebDriver driver;
+
+    // Used for signing admin action
+    protected static RealmModel appRealm;
+
+
+    @Test
+    public void testBasic() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                Map<String,String> initParams = new TreeMap<String,String>();
+                initParams.put(CONFIG_FILE_INIT_PARAM, "classpath:jaxrs-test/jaxrs-keycloak.json");
+                keycloakRule.deployJaxrsApplication("JaxrsSimpleApp", "/jaxrs-simple", JaxrsTestApplication.class, initParams);
+            }
+
+        });
+
+        // Send GET request without token, it should fail
+        Response getResp = client.target(JAXRS_APP_URL).request().get();
+        Assert.assertEquals(getResp.getStatus(), 401);
+        getResp.close();
+
+        // Send POST request without token, it should fail
+        Response postResp = client.target(JAXRS_APP_URL).request().post(Entity.form(new Form()));
+        Assert.assertEquals(postResp.getStatus(), 401);
+        postResp.close();
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        // Send GET request with token and assert it's passing
+        JaxrsTestResource.SimpleRepresentation getRep = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get(JaxrsTestResource.SimpleRepresentation.class);
+        Assert.assertEquals("get", getRep.getMethod());
+        Assert.assertTrue(getRep.getHasUserRole());
+        Assert.assertFalse(getRep.getHasAdminRole());
+        Assert.assertFalse(getRep.getHasJaxrsAppRole());
+        // Assert that principal is ID of user (should be in UUID format)
+        UUID.fromString(getRep.getPrincipal());
+
+        // Send POST request with token and assert it's passing
+        JaxrsTestResource.SimpleRepresentation postRep = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .post(Entity.form(new Form()), JaxrsTestResource.SimpleRepresentation.class);
+        Assert.assertEquals("post", postRep.getMethod());
+        Assert.assertEquals(getRep.getPrincipal(), postRep.getPrincipal());
+    }
+
+    @Test
+    public void testRelativeUriAndPublicKey() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                Map<String,String> initParams = new TreeMap<String,String>();
+                initParams.put(CONFIG_FILE_INIT_PARAM, "classpath:jaxrs-test/jaxrs-keycloak-relative.json");
+                keycloakRule.deployJaxrsApplication("JaxrsSimpleApp", "/jaxrs-simple", JaxrsTestApplication.class, initParams);
+            }
+
+        });
+
+        // Send GET request without token, it should fail
+        Response getResp = client.target(JAXRS_APP_URL).request().get();
+        Assert.assertEquals(getResp.getStatus(), 401);
+        getResp.close();
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        // Send GET request with token and assert it's passing
+        JaxrsTestResource.SimpleRepresentation getRep = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get(JaxrsTestResource.SimpleRepresentation.class);
+        Assert.assertEquals("get", getRep.getMethod());
+        Assert.assertTrue(getRep.getHasUserRole());
+        Assert.assertFalse(getRep.getHasAdminRole());
+        Assert.assertFalse(getRep.getHasJaxrsAppRole());
+        // Assert that principal is ID of user (should be in UUID format)
+        UUID.fromString(getRep.getPrincipal());
+    }
+
+    @Test
+    public void testSslRequired() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                Map<String, String> initParams = new TreeMap<String, String>();
+                initParams.put(CONFIG_FILE_INIT_PARAM, "classpath:jaxrs-test/jaxrs-keycloak-ssl.json");
+                keycloakRule.deployJaxrsApplication("JaxrsSimpleApp", "/jaxrs-simple", JaxrsTestApplication.class, initParams);
+            }
+
+        });
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        // Fail due to non-https
+        Response getResp = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get();
+        Assert.assertEquals(getResp.getStatus(), 403);
+        getResp.close();
+    }
+
+    @Test
+    public void testResourceRoleMappings() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                Map<String, String> initParams = new TreeMap<String, String>();
+                initParams.put(CONFIG_FILE_INIT_PARAM, "classpath:jaxrs-test/jaxrs-keycloak-resource-mappings.json");
+                keycloakRule.deployJaxrsApplication("JaxrsSimpleApp", "/jaxrs-simple", JaxrsTestApplication.class, initParams);
+            }
+
+        });
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        // Send GET request with token and assert it's passing
+        JaxrsTestResource.SimpleRepresentation getRep = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get(JaxrsTestResource.SimpleRepresentation.class);
+        Assert.assertEquals("get", getRep.getMethod());
+
+        // principal is username
+        Assert.assertEquals("test-user@localhost", getRep.getPrincipal());
+
+        // User is in jaxrs-app-user role thanks to use-resource-role-mappings
+        Assert.assertFalse(getRep.getHasUserRole());
+        Assert.assertFalse(getRep.getHasAdminRole());
+        Assert.assertTrue(getRep.getHasJaxrsAppRole());
+    }
+
+    @Test
+    public void testCors() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                Map<String,String> initParams = new TreeMap<String,String>();
+                initParams.put(CONFIG_FILE_INIT_PARAM, "classpath:jaxrs-test/jaxrs-keycloak.json");
+                keycloakRule.deployJaxrsApplication("JaxrsSimpleApp", "/jaxrs-simple", JaxrsTestApplication.class, initParams);
+            }
+
+        });
+
+        // Send OPTIONS request
+        Response optionsResp = client.target(JAXRS_APP_URL).request()
+                .header(CorsHeaders.ORIGIN, "http://localhost:8081")
+                .options();
+        Assert.assertEquals("true", optionsResp.getHeaderString(CorsHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS));
+        Assert.assertEquals("http://localhost:8081", optionsResp.getHeaderString(CorsHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
+        optionsResp.close();
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        // Send GET request with token but bad origin
+        Response badOriginResp = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .header(CorsHeaders.ORIGIN, "http://evil.org")
+                .get();
+        Assert.assertEquals(403, badOriginResp.getStatus());
+        badOriginResp.close();
+
+        // Send GET request with token and good origin
+        Response goodResp = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .header(CorsHeaders.ORIGIN, "http://localhost:8081")
+                .get();
+        Assert.assertEquals(200, goodResp.getStatus());
+        Assert.assertEquals("true", optionsResp.getHeaderString(CorsHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS));
+        Assert.assertEquals("http://localhost:8081", optionsResp.getHeaderString(CorsHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
+        JaxrsTestResource.SimpleRepresentation getRep = goodResp.readEntity(JaxrsTestResource.SimpleRepresentation.class);
+        Assert.assertEquals("get", getRep.getMethod());
+        goodResp.close();
+    }
+
+    @Test
+    public void testPushNotBefore() {
+        keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+            @Override
+            public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+                Map<String,String> initParams = new TreeMap<String,String>();
+                initParams.put(CONFIG_FILE_INIT_PARAM, "classpath:jaxrs-test/jaxrs-keycloak.json");
+                keycloakRule.deployJaxrsApplication("JaxrsSimpleApp", "/jaxrs-simple", JaxrsTestApplication.class, initParams);
+            }
+
+        });
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        // Send GET request with token and assert it's passing
+        JaxrsTestResource.SimpleRepresentation getRep = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get(JaxrsTestResource.SimpleRepresentation.class);
+        Assert.assertEquals("get", getRep.getMethod());
+        Assert.assertTrue(getRep.getHasUserRole());
+
+        // Push new notBefore now TODO: should use admin console (admin client) instead..
+        int currentTime = Time.currentTime();
+        PushNotBeforeAction action = new PushNotBeforeAction(TokenIdGenerator.generateId(), currentTime + 30, "jaxrs-app", currentTime + 1);
+        String token = new TokenManager().encodeToken(appRealm, action);
+        Response response = client.target(JAXRS_APP_PUSN_NOT_BEFORE_URL).request().post(Entity.text(token));
+        Assert.assertEquals(204, response.getStatus());
+        response.close();
+
+        // Assert that previous token shouldn't pass anymore
+        response = client.target(JAXRS_APP_URL).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get();
+        Assert.assertEquals(401, response.getStatus());
+        response.close();
+    }
+
+    // @Test
+    public void testCxfExample() {
+        String uri = "http://localhost:9000/customerservice/customers/123";
+        Response resp = client.target(uri).request()
+                .get();
+        Assert.assertEquals(resp.getStatus(), 401);
+        resp.close();
+
+        // Retrieve token
+        OAuthClient.AccessTokenResponse accessTokenResp = retrieveAccessToken();
+        String authHeader = "Bearer " + accessTokenResp.getAccessToken();
+
+        String resp2 = client.target(uri).request()
+                .header(HttpHeaders.AUTHORIZATION, authHeader)
+                .get(String.class);
+        System.out.println(resp2);
+    }
+
+
+    private OAuthClient.AccessTokenResponse retrieveAccessToken() {
+        OAuthClient oauth = new OAuthClient(driver);
+        oauth.doLogin("test-user@localhost", "password");
+        String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
+        OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
+        Assert.assertEquals(200, response.getStatusCode());
+        return response;
+    }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsTestApplication.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsTestApplication.java
new file mode 100644
index 0000000..787b9fd
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsTestApplication.java
@@ -0,0 +1,38 @@
+package org.keycloak.testsuite.jaxrs;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+
+import org.keycloak.jaxrs.JaxrsBearerTokenFilterImpl;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class JaxrsTestApplication extends Application {
+
+    protected Set<Class<?>> classes = new HashSet<Class<?>>();
+    protected Set<Object> singletons = new HashSet<Object>();
+
+    public JaxrsTestApplication(@Context ServletContext context) throws Exception {
+        singletons.add(new JaxrsTestResource());
+
+        String configFile = context.getInitParameter(JaxrsFilterTest.CONFIG_FILE_INIT_PARAM);
+        JaxrsBearerTokenFilterImpl filter = new JaxrsBearerTokenFilterImpl();
+        filter.setKeycloakConfigFile(configFile);
+        singletons.add(filter);
+    }
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        return classes;
+    }
+
+    @Override
+    public Set<Object> getSingletons() {
+        return singletons;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsTestResource.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsTestResource.java
new file mode 100644
index 0000000..6938d05
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsTestResource.java
@@ -0,0 +1,93 @@
+package org.keycloak.testsuite.jaxrs;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.SecurityContext;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@Path("res")
+public class JaxrsTestResource {
+
+    @Context
+    protected SecurityContext securityContext;
+
+    @GET
+    @Produces("application/json")
+    public SimpleRepresentation get() {
+        return new SimpleRepresentation("get", securityContext.getUserPrincipal().getName(), securityContext.isUserInRole("user"),
+                securityContext.isUserInRole("admin"), securityContext.isUserInRole("jaxrs-app-user"));
+    }
+
+    @POST
+    @Produces("application/json")
+    public SimpleRepresentation post() {
+        return new SimpleRepresentation("post", securityContext.getUserPrincipal().getName(), securityContext.isUserInRole("user"),
+                securityContext.isUserInRole("admin"), securityContext.isUserInRole("jaxrs-app-user"));
+    }
+
+    public static class SimpleRepresentation {
+        private String method;
+        private String principal;
+        private Boolean hasUserRole;
+        private Boolean hasAdminRole;
+        private Boolean hasJaxrsAppRole;
+
+        public SimpleRepresentation() {
+        }
+
+        public SimpleRepresentation(String method, String principal, boolean hasUserRole, boolean hasAdminRole,
+                                    boolean hasJaxrsAppRole) {
+            this.method = method;
+            this.principal = principal;
+            this.hasUserRole = hasUserRole;
+            this.hasAdminRole = hasAdminRole;
+            this.hasJaxrsAppRole = hasJaxrsAppRole;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+
+        public void setMethod(String method) {
+            this.method = method;
+        }
+
+        public String getPrincipal() {
+            return principal;
+        }
+
+        public void setPrincipal(String principal) {
+            this.principal = principal;
+        }
+
+        public Boolean getHasUserRole() {
+            return hasUserRole;
+        }
+
+        public void setHasUserRole(Boolean hasUserRole) {
+            this.hasUserRole = hasUserRole;
+        }
+
+        public Boolean getHasAdminRole() {
+            return hasAdminRole;
+        }
+
+        public void setHasAdminRole(Boolean hasAdminRole) {
+            this.hasAdminRole = hasAdminRole;
+        }
+
+        public Boolean getHasJaxrsAppRole() {
+            return hasJaxrsAppRole;
+        }
+
+        public void setHasJaxrsAppRole(Boolean hasJaxrsAppRole) {
+            this.hasJaxrsAppRole = hasJaxrsAppRole;
+        }
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
index 0808dcb..b89f2c3 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
@@ -1,10 +1,14 @@
 package org.keycloak.testsuite.rule;
 
+import io.undertow.servlet.Servlets;
 import io.undertow.servlet.api.DeploymentInfo;
+import io.undertow.servlet.api.FilterInfo;
 import io.undertow.servlet.api.LoginConfig;
 import io.undertow.servlet.api.SecurityConstraint;
 import io.undertow.servlet.api.ServletInfo;
 import io.undertow.servlet.api.WebResourceCollection;
+import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
+import org.jboss.resteasy.spi.ResteasyDeployment;
 import org.junit.rules.ExternalResource;
 import org.keycloak.Config;
 import org.keycloak.models.KeycloakSession;
@@ -14,16 +18,23 @@ import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.services.filters.ClientConnectionFilter;
+import org.keycloak.services.filters.KeycloakSessionServletFilter;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.Retry;
 import org.keycloak.testutils.KeycloakServer;
 import org.keycloak.util.JsonSerialization;
 
+import javax.servlet.DispatcherType;
 import javax.servlet.Servlet;
+import javax.ws.rs.core.Application;
+
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.Socket;
+import java.util.Map;
+
 import org.keycloak.adapters.KeycloakConfigResolver;
 
 /**
@@ -158,6 +169,22 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         server.getServer().deploy(di);
     }
 
+    public void deployJaxrsApplication(String name, String contextPath, Class<? extends Application> applicationClass, Map<String,String> initParams) {
+        ResteasyDeployment deployment = new ResteasyDeployment();
+        deployment.setApplicationClass(applicationClass.getName());
+
+        DeploymentInfo di = server.getServer().undertowDeployment(deployment, "");
+        di.setClassLoader(getClass().getClassLoader());
+        di.setContextPath(contextPath);
+        di.setDeploymentName(name);
+
+        for (Map.Entry<String,String> param : initParams.entrySet()) {
+            di.addInitParameter(param.getKey(), param.getValue());
+        }
+
+        server.getServer().deploy(di);
+    }
+
     @Override
     protected void after() {
         removeTestRealms();
diff --git a/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak.json b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak.json
new file mode 100644
index 0000000..5a83668
--- /dev/null
+++ b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak.json
@@ -0,0 +1,9 @@
+{
+    "realm": "test",
+    "resource": "jaxrs-app",
+    "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
diff --git a/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-relative.json b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-relative.json
new file mode 100644
index 0000000..a17933e
--- /dev/null
+++ b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-relative.json
@@ -0,0 +1,7 @@
+{
+    "realm": "test",
+    "resource": "jaxrs-app",
+    "auth-server-url": "/auth",
+    "ssl-required" : "external",
+    "bearer-only": true
+}
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-resource-mappings.json b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-resource-mappings.json
new file mode 100644
index 0000000..924e4ad
--- /dev/null
+++ b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-resource-mappings.json
@@ -0,0 +1,10 @@
+{
+    "realm": "test",
+    "resource": "jaxrs-app",
+    "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+    "auth-server-url": "http://localhost:8081/auth",
+    "ssl-required" : "external",
+    "bearer-only": true,
+    "principal-attribute": "preferred_username",
+    "use-resource-role-mappings": true
+}
diff --git a/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-ssl.json b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-ssl.json
new file mode 100644
index 0000000..666ddb9
--- /dev/null
+++ b/testsuite/integration/src/test/resources/jaxrs-test/jaxrs-keycloak-ssl.json
@@ -0,0 +1,8 @@
+{
+    "realm": "test",
+    "resource": "jaxrs-app",
+    "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+    "auth-server-url": "http://localhost:8081/auth",
+    "ssl-required" : "all",
+    "bearer-only": true
+}
\ No newline at end of file
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java
index 5fd6c01..cfbe9e1 100755
--- a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/PerfAppServlet.java
@@ -4,7 +4,7 @@ import freemarker.cache.ClassTemplateLoader;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
-import org.keycloak.adapters.AdapterConstants;
+import org.keycloak.constants.AdapterConstants;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.RefreshToken;
 import org.keycloak.util.Time;
diff --git a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
index 791e0d3..18b1de7 100755
--- a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
+++ b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
@@ -36,7 +36,6 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.oidc.OpenIDConnectService;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.admin.AdminRoot;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 import org.keycloak.testsuite.rule.WebResource;
@@ -48,18 +47,12 @@ 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.WebTarget;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.UriBuilder;
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URL;
 import java.security.Principal;
-import java.util.Map;
 import java.util.regex.Matcher;
 
 /**