Merge pull request #3088 from thomasdarimont/issue/KEYCLOAK-3380-allow-ignore-pattern-in-filter
KEYCLOAK-3380 Allow to configure paths to skip in KeycloakOIDCFilter
This commit is contained in:
commit
1e7cf9fb3f
1 changed files with 47 additions and 7 deletions
|
@ -47,6 +47,7 @@ import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -56,10 +57,18 @@ public class KeycloakOIDCFilter implements Filter {
|
||||||
protected AdapterDeploymentContext deploymentContext;
|
protected AdapterDeploymentContext deploymentContext;
|
||||||
protected SessionIdMapper idMapper = new InMemorySessionIdMapper();
|
protected SessionIdMapper idMapper = new InMemorySessionIdMapper();
|
||||||
protected NodesRegistrationManagement nodesRegistrationManagement;
|
protected NodesRegistrationManagement nodesRegistrationManagement;
|
||||||
|
protected Pattern skipPattern;
|
||||||
|
|
||||||
private final static Logger log = Logger.getLogger(""+KeycloakOIDCFilter.class);
|
private final static Logger log = Logger.getLogger(""+KeycloakOIDCFilter.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(final FilterConfig filterConfig) throws ServletException {
|
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");
|
String configResolverClass = filterConfig.getInitParameter("keycloak.config.resolver");
|
||||||
if (configResolverClass != null) {
|
if (configResolverClass != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -85,13 +94,7 @@ public class KeycloakOIDCFilter implements Filter {
|
||||||
if (pathParam != null) path = pathParam;
|
if (pathParam != null) path = pathParam;
|
||||||
is = filterConfig.getServletContext().getResourceAsStream(path);
|
is = filterConfig.getServletContext().getResourceAsStream(path);
|
||||||
}
|
}
|
||||||
KeycloakDeployment kd;
|
KeycloakDeployment kd = createKeycloakDeploymentFrom(is);
|
||||||
if (is == null) {
|
|
||||||
log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
|
|
||||||
kd = new KeycloakDeployment();
|
|
||||||
} else {
|
|
||||||
kd = KeycloakDeploymentBuilder.build(is);
|
|
||||||
}
|
|
||||||
deploymentContext = new AdapterDeploymentContext(kd);
|
deploymentContext = new AdapterDeploymentContext(kd);
|
||||||
log.fine("Keycloak is using a per-deployment configuration.");
|
log.fine("Keycloak is using a per-deployment configuration.");
|
||||||
}
|
}
|
||||||
|
@ -99,13 +102,30 @@ public class KeycloakOIDCFilter implements Filter {
|
||||||
nodesRegistrationManagement = new NodesRegistrationManagement();
|
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
|
@Override
|
||||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
||||||
|
|
||||||
log.fine("Keycloak OIDC Filter");
|
log.fine("Keycloak OIDC Filter");
|
||||||
//System.err.println("Keycloak OIDC Filter: " + ((HttpServletRequest)req).getRequestURL().toString());
|
//System.err.println("Keycloak OIDC Filter: " + ((HttpServletRequest)req).getRequestURL().toString());
|
||||||
HttpServletRequest request = (HttpServletRequest) req;
|
HttpServletRequest request = (HttpServletRequest) req;
|
||||||
HttpServletResponse response = (HttpServletResponse) res;
|
HttpServletResponse response = (HttpServletResponse) res;
|
||||||
|
|
||||||
|
if (shouldSkip(request)) {
|
||||||
|
chain.doFilter(req, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response);
|
OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response);
|
||||||
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
|
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||||
if (deployment == null || !deployment.isConfigured()) {
|
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
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue