keycloak-uncached

KEYCLOAK-3380 Allow to configure paths to skip in KeycloakOIDCFilter We

7/30/2016 11:09:54 AM

Details

diff --git a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java
index dab7501..fc13616 100755
--- a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java
+++ b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/KeycloakOIDCFilter.java
@@ -47,6 +47,7 @@ import java.io.InputStream;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Pattern;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -56,10 +57,18 @@ public class KeycloakOIDCFilter implements Filter {
     protected AdapterDeploymentContext deploymentContext;
     protected SessionIdMapper idMapper = new InMemorySessionIdMapper();
     protected NodesRegistrationManagement nodesRegistrationManagement;
+    protected Pattern skipPattern;
+
     private final static Logger log = Logger.getLogger(""+KeycloakOIDCFilter.class);
 
     @Override
     public void init(final FilterConfig filterConfig) throws ServletException {
+
+        String skipPatternDefinition = filterConfig.getInitParameter("keycloak.config.skipPattern");
+        if (skipPatternDefinition != null) {
+            skipPattern = Pattern.compile(skipPatternDefinition, Pattern.DOTALL);
+        }
+
         String configResolverClass = filterConfig.getInitParameter("keycloak.config.resolver");
         if (configResolverClass != null) {
             try {
@@ -85,13 +94,7 @@ public class KeycloakOIDCFilter implements Filter {
                 if (pathParam != null) path = pathParam;
                 is = filterConfig.getServletContext().getResourceAsStream(path);
             }
-            KeycloakDeployment kd;
-            if (is == null) {
-                log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
-                kd = new KeycloakDeployment();
-            } else {
-                kd = KeycloakDeploymentBuilder.build(is);
-            }
+            KeycloakDeployment kd = createKeycloakDeploymentFrom(is);
             deploymentContext = new AdapterDeploymentContext(kd);
             log.fine("Keycloak is using a per-deployment configuration.");
         }
@@ -99,13 +102,30 @@ public class KeycloakOIDCFilter implements Filter {
         nodesRegistrationManagement = new NodesRegistrationManagement();
     }
 
+    private KeycloakDeployment createKeycloakDeploymentFrom(InputStream is) {
+
+        if (is == null) {
+            log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
+            return new KeycloakDeployment();
+        }
+
+        return KeycloakDeploymentBuilder.build(is);
+    }
+
 
     @Override
     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
+
         log.fine("Keycloak OIDC Filter");
         //System.err.println("Keycloak OIDC Filter: " + ((HttpServletRequest)req).getRequestURL().toString());
         HttpServletRequest request = (HttpServletRequest) req;
         HttpServletResponse response = (HttpServletResponse) res;
+
+        if (shouldSkip(request)) {
+            chain.doFilter(req, res);
+            return;
+        }
+
         OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response);
         KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
         if (deployment == null || !deployment.isConfigured()) {
@@ -171,6 +191,26 @@ public class KeycloakOIDCFilter implements Filter {
 
     }
 
+    /**
+     * Decides whether this {@link Filter} should skip the given {@link HttpServletRequest} based on the configured {@link KeycloakOIDCFilter#skipPattern}.
+     * Patterns are matched against the {@link HttpServletRequest#getRequestURI() requestURI} of a request without the context-path.
+     * A request for {@code /myapp/index.html} would be tested with {@code /index.html} against the skip pattern.
+     * Skipped requests will not be processed further by {@link KeycloakOIDCFilter} and immediately delegated to the {@link FilterChain}.
+     *
+     * @param request the request to check
+     * @return {@code true} if the request should not be handled,
+     *         {@code false} otherwise.
+     */
+    private boolean shouldSkip(HttpServletRequest request) {
+
+        if (skipPattern == null) {
+            return false;
+        }
+
+        String requestPath = request.getRequestURI().substring(request.getContextPath().length());
+        return skipPattern.matcher(requestPath).matches();
+    }
+
     @Override
     public void destroy() {