Merge pull request #66 from Unicon/CASC-210
CASC-210: Added support for having regex expressions in the proxy (chaining) list.
This commit is contained in:
commit
0a7ffac846
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@
|
|||
package org.jasig.cas.client.validation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
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.
|
||||
|
|
@ -32,11 +36,28 @@ import org.jasig.cas.client.util.CommonUtils;
|
|||
*/
|
||||
public final class ProxyList {
|
||||
|
||||
private final List<String[]> proxyChains;
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final List<List<UrlPatternMatcherStrategy>> proxyChains;
|
||||
|
||||
public ProxyList(final List<String[]> proxyChains) {
|
||||
CommonUtils.assertNotNull(proxyChains, "List of proxy chains cannot be null.");
|
||||
this.proxyChains = proxyChains;
|
||||
|
||||
this.proxyChains = new ArrayList<List<UrlPatternMatcherStrategy>>();
|
||||
|
||||
for (final String[] list : proxyChains) {
|
||||
final List<UrlPatternMatcherStrategy> chain = new ArrayList<UrlPatternMatcherStrategy>();
|
||||
|
||||
for (final String item : list) {
|
||||
if (item.startsWith("^")) {
|
||||
chain.add(new RegexUrlPatternMatcherStrategy(item));
|
||||
} else {
|
||||
chain.add(new ExactUrlPatternMatcherStrategy(item));
|
||||
}
|
||||
}
|
||||
|
||||
this.proxyChains.add(chain);
|
||||
}
|
||||
}
|
||||
|
||||
public ProxyList() {
|
||||
|
|
@ -44,12 +65,33 @@ public final class ProxyList {
|
|||
}
|
||||
|
||||
public boolean contains(final String[] proxiedList) {
|
||||
for (final String[] list : this.proxyChains) {
|
||||
if (Arrays.equals(proxiedList, list)) {
|
||||
return true;
|
||||
StringBuilder loggingOutput;
|
||||
|
||||
for (final List<UrlPatternMatcherStrategy> proxyChain : this.proxyChains) {
|
||||
loggingOutput = new StringBuilder();
|
||||
|
||||
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.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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,37 @@ public final class Cas20ProxyTicketValidatorTests extends AbstractTicketValidato
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegexProxyChainWithValidProxy() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final List<String[]> list = new ArrayList<String[]>();
|
||||
list.add(new String[] { "proxy1", "proxy2", "^proxy3/[a-z]*/" });
|
||||
this.ticketValidator.setAllowedProxyChains(new ProxyList(list));
|
||||
|
||||
final String USERNAME = "username";
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>username</cas:user><cas:proxyGrantingTicket>PGTIOU-84678-8a9d...</cas:proxyGrantingTicket><cas:proxies><cas:proxy>proxy1</cas:proxy><cas:proxy>proxy2</cas:proxy><cas:proxy>proxy3/abc/</cas:proxy></cas:proxies></cas:authenticationSuccess></cas:serviceResponse>";
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
|
||||
final Assertion assertion = this.ticketValidator.validate("test", "test");
|
||||
assertEquals(USERNAME, assertion.getPrincipal().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegexProxyChainWithInvalidProxy() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final List<String[]> list = new ArrayList<String[]>();
|
||||
list.add(new String[] { "proxy1", "proxy2", "^proxy3/[a-z]*/" });
|
||||
this.ticketValidator.setAllowedProxyChains(new ProxyList(list));
|
||||
|
||||
final String RESPONSE = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'><cas:authenticationSuccess><cas:user>username</cas:user><cas:proxyGrantingTicket>PGTIOU-84678-8a9d...</cas:proxyGrantingTicket><cas:proxies><cas:proxy>proxy1</cas:proxy><cas:proxy>proxy2</cas:proxy><cas:proxy>proxy3/ABC/</cas:proxy></cas:proxies></cas:authenticationSuccess></cas:serviceResponse>";
|
||||
server.content = RESPONSE.getBytes(server.encoding);
|
||||
|
||||
try {
|
||||
this.ticketValidator.validate("test", "test");
|
||||
fail("Invalid proxy chain");
|
||||
} catch (InvalidProxyChainTicketValidationException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructionFromSpringBean() throws TicketValidationException, UnsupportedEncodingException {
|
||||
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
|
|
|
|||
Loading…
Reference in New Issue