From 99763ab2b6b11ceabd8b3641e64132929bfd4bcd Mon Sep 17 00:00:00 2001 From: John Gasper Date: Mon, 14 Apr 2014 08:45:21 -0700 Subject: [PATCH] Using Misagh's PatternMatcherStrategy to optimize proxy chain checks --- .../ExactUrlPatternMatcherStrategy.java | 8 +++- .../RegexUrlPatternMatcherStrategy.java | 6 +++ .../cas/client/validation/ProxyList.java | 48 ++++++++++++------- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java index 64f20eb..9fd0ddf 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java @@ -28,7 +28,13 @@ package org.jasig.cas.client.authentication; public final class ExactUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy { private String pattern; - + + public ExactUrlPatternMatcherStrategy() {} + + public ExactUrlPatternMatcherStrategy(final String pattern) { + this.setPattern(pattern); + } + public boolean matches(final String url) { return url.equals(this.pattern); } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java index a941459..e5665cd 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java @@ -30,6 +30,12 @@ import java.util.regex.Pattern; public final class RegexUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy { private Pattern pattern; + + public RegexUrlPatternMatcherStrategy() {} + + public RegexUrlPatternMatcherStrategy(final String pattern) { + this.setPattern(pattern); + } public boolean matches(final String url) { return this.pattern.matcher(url).find(); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java index 3a6846c..606923c 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java @@ -19,10 +19,13 @@ package org.jasig.cas.client.validation; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.regex.Pattern; +import org.jasig.cas.client.authentication.ExactUrlPatternMatcherStrategy; +import org.jasig.cas.client.authentication.RegexUrlPatternMatcherStrategy; +import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy; import org.jasig.cas.client.util.CommonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Holding class for the proxy list to make Spring configuration easier. @@ -33,20 +36,28 @@ import org.jasig.cas.client.util.CommonUtils; */ public final class ProxyList { - private final List proxyChains; - private final HashMap proxyChainRegexCache; + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final List> proxyChains; public ProxyList(final List proxyChains) { CommonUtils.assertNotNull(proxyChains, "List of proxy chains cannot be null."); - this.proxyChains = proxyChains; - this.proxyChainRegexCache = new HashMap(); - for (final String[] list : this.proxyChains) { + this.proxyChains = new ArrayList>(); + + for (final String[] list : proxyChains) { + final List chain = new ArrayList(); + for (final String item : list) { if (item.startsWith("^")) { - this.proxyChainRegexCache.put(item, Pattern.compile(item)); + chain.add(new RegexUrlPatternMatcherStrategy(item)); + } + else { + chain.add(new ExactUrlPatternMatcherStrategy(item)); } } + + this.proxyChains.add(chain); } } @@ -55,28 +66,33 @@ public final class ProxyList { } public boolean contains(String[] proxiedList) { - for (final String[] proxyChain : this.proxyChains) { + StringBuilder loggingOutput; - if (proxyChain.length == proxiedList.length) { + for (final List proxyChain : this.proxyChains) { + loggingOutput = new StringBuilder(); - for (int linkIndex = 0; linkIndex < proxyChain.length; linkIndex++) { - String link = proxyChain[linkIndex]; - - if (link.equals(proxiedList[linkIndex]) - || (link.startsWith("^") && proxyChainRegexCache.get(link).matcher(proxiedList[linkIndex]).matches())) { + if (proxyChain.size() == proxiedList.length) { + for (int linkIndex = 0; linkIndex < proxyChain.size(); linkIndex++) { + final String linkToTest = proxiedList[linkIndex]; + loggingOutput.append(linkToTest); + if (proxyChain.get(linkIndex).matches(linkToTest)) { //If we are at the last link, we found a good proxyChain. - if (linkIndex == proxyChain.length-1) { + if (linkIndex == proxyChain.size()-1) { + logger.info("Proxy chain matched: {}", loggingOutput.toString()); return true; } } else { + logger.warn("Proxy chain did not match at {}. Skipping to next allowedProxyChain", loggingOutput.toString()); break; } + loggingOutput.append("->"); } } } + logger.warn("No proxy chain matched the allowedProxyChains list."); return false; }