CAS-219: Provide support for certain urls to be excluded from CAS filters.

This commit is contained in:
Misagh Moayyed 2014-02-27 22:02:19 -07:00
parent 590a79c6a6
commit c857e4610b
7 changed files with 191 additions and 13 deletions

View File

@ -98,8 +98,16 @@ public class AuthenticationFilter extends AbstractCasFilter {
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
if (isRequestUrlExcluded(request)) {
logger.debug("Request is ignored.");
filterChain.doFilter(request, response);
return;
}
final HttpSession session = request.getSession(false);
final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;

View File

@ -18,6 +18,10 @@
*/
package org.jasig.cas.client.util;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -48,6 +52,9 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
/** Defines the parameter to look for for the service. */
private String serviceParameterName = "service";
/** Url pattern for this filter to exclude and ignore. **/
private Pattern ignorePattern = null;
/** Sets where response.encodeUrl should be called on service urls when constructed. */
private boolean encodeServiceUrl = true;
@ -72,6 +79,12 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
setEncodeServiceUrl(parseBoolean(getPropertyFromInitParams(filterConfig, "encodeServiceUrl", "true")));
logger.trace("Loading encodeServiceUrl property: {}", this.encodeServiceUrl);
final String ignorePattern = getPropertyFromInitParams(filterConfig, "ignorePattern", null);
if (ignorePattern != null) {
setIgnorePattern(Pattern.compile(ignorePattern));
logger.trace("Loading ignorePattern property: {}", this.ignorePattern.pattern());
}
initInternal(filterConfig);
}
init();
@ -148,6 +161,10 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
return this.serviceParameterName;
}
public final void setIgnorePattern(final Pattern patternToIgnore) {
this.ignorePattern = patternToIgnore;
}
/**
* Template method to allow you to change how you retrieve the ticket.
*
@ -157,4 +174,20 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
protected String retrieveTicketFromRequest(final HttpServletRequest request) {
return CommonUtils.safeGetParameter(request, getArtifactParameterName());
}
protected boolean isRequestUrlExcluded(final HttpServletRequest request) {
boolean result = false;
if (this.ignorePattern != null) {
final StringBuffer urlBuffer = request.getRequestURL();
if (request.getQueryString() != null) {
urlBuffer.append("?").append(request.getQueryString());
}
final String requestUri = urlBuffer.toString();
logger.debug("Checking [{}] against pattern [{}]", requestUri, this.ignorePattern.pattern());
result = this.ignorePattern.matcher(requestUri).find();
} else {
logger.debug("Ignore pattern is not defined");
}
return result;
}
}

View File

@ -190,13 +190,19 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
if (isRequestUrlExcluded(request)) {
logger.debug("Request is ignored.");
filterChain.doFilter(request, response);
return;
}
if (!preFilter(servletRequest, servletResponse, filterChain)) {
return;
}
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final String ticket = retrieveTicketFromRequest(request);
if (CommonUtils.isNotBlank(ticket)) {

View File

@ -37,7 +37,6 @@ import org.springframework.mock.web.*;
* Tests for the AuthenticationFilter.
*
* @author Scott Battaglia
* @version $Revision: 11753 $ $Date: 2007-01-03 13:37:26 -0500 (Wed, 03 Jan 2007) $
* @since 3.0
*/
public final class AuthenticationFilterTests {
@ -50,11 +49,10 @@ public final class AuthenticationFilterTests {
@Before
public void setUp() throws Exception {
// TODO CAS_SERVICE_URL, false, CAS_LOGIN_URL
this.filter = new AuthenticationFilter();
final MockFilterConfig config = new MockFilterConfig();
config.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL);
config.addInitParameter("service", "https://localhost:8443/service");
config.addInitParameter("service", CAS_SERVICE_URL);
this.filter.init(config);
}
@ -184,7 +182,7 @@ public final class AuthenticationFilterTests {
final AuthenticationFilter f = new AuthenticationFilter();
final MockFilterConfig config = new MockFilterConfig();
config.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL);
config.addInitParameter("service", "https://localhost:8443/service");
config.addInitParameter("service", CAS_SERVICE_URL);
config.addInitParameter("renew", "true");
try {
f.init(config);
@ -198,8 +196,8 @@ public final class AuthenticationFilterTests {
public void testAllowsRenewContextParam() throws Exception {
final AuthenticationFilter f = new AuthenticationFilter();
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerLoginUrl", "https://cas.example.com/login");
context.addInitParameter("service", "https://localhost:8443/service");
context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL);
context.addInitParameter("service", CAS_SERVICE_URL);
context.addInitParameter("renew", "true");
f.init(new MockFilterConfig(context));
final Field renewField = AuthenticationFilter.class.getDeclaredField("renew");
@ -211,10 +209,38 @@ public final class AuthenticationFilterTests {
public void customRedirectStrategy() throws Exception {
final AuthenticationFilter f = new AuthenticationFilter();
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerLoginUrl", "https://cas.example.com/login");
context.addInitParameter("service", "https://localhost:8443/service");
context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL);
context.addInitParameter("service", CAS_SERVICE_URL);
context.addInitParameter("authenticationRedirectStrategyClass",
"org.jasig.cas.client.authentication.FacesCompatibleAuthenticationRedirectStrategy");
f.init(new MockFilterConfig(context));
}
@Test
public void testIgnorePatterns() throws Exception {
final AuthenticationFilter f = new AuthenticationFilter();
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL);
context.addInitParameter("ignorePattern", "=valueTo(\\w+)");
context.addInitParameter("service", CAS_SERVICE_URL);
f.init(new MockFilterConfig(context));
final MockHttpServletRequest request = new MockHttpServletRequest();
final String URL = CAS_SERVICE_URL + "?param=valueToIgnore";
request.setRequestURI(URL);
final MockHttpSession session = new MockHttpSession();
request.setSession(session);
final MockHttpServletResponse response = new MockHttpServletResponse();
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
}
};
f.doFilter(request, response, filterChain);
assertNull(response.getRedirectedUrl());
}
}

View File

@ -20,8 +20,19 @@ package org.jasig.cas.client.validation;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.junit.Test;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockServletContext;
/**
@ -54,4 +65,39 @@ public class Cas10TicketValidationFilterTests {
assertTrue(validator instanceof Cas10TicketValidator);
assertTrue(((Cas10TicketValidator) validator).isRenew());
}
@Test
public void testIgnorePatterns() throws Exception {
final Cas10TicketValidationFilter f = new Cas10TicketValidationFilter();
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerUrlPrefix", "https://cas.example.com");
context.addInitParameter("serverName", "https://localhost:8443");
context.addInitParameter("ignorePattern", "=valueTo(\\w+)");
f.init(new MockFilterConfig(context));
final MockHttpServletRequest request = new MockHttpServletRequest();
final String URL = "https://localhost:8443/?param=valueToIgnore";
request.setRequestURI(URL);
request.setQueryString("ticket=ST-1234");
request.setParameter("ticket", "ST-1234");
final MockHttpSession session = new MockHttpSession();
request.setSession(session);
final MockHttpServletResponse response = new MockHttpServletResponse();
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
}
};
try {
f.doFilter(request, response, filterChain);
} catch (final Exception e) {
fail("The validation request should have been ignored");
}
}
}

View File

@ -20,8 +20,19 @@ package org.jasig.cas.client.validation;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.junit.Test;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockServletContext;
/**
@ -54,4 +65,39 @@ public class Saml11TicketValidationFilterTests {
assertTrue(validator instanceof Saml11TicketValidator);
assertTrue(((Saml11TicketValidator) validator).isRenew());
}
@Test
public void testIgnorePatterns() throws Exception {
final Saml11TicketValidationFilter f = new Saml11TicketValidationFilter();
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerUrlPrefix", "https://cas.example.com");
context.addInitParameter("serverName", "https://localhost:8443");
context.addInitParameter("ignorePattern", "=valueTo(\\w+)");
f.init(new MockFilterConfig(context));
final MockHttpServletRequest request = new MockHttpServletRequest();
final String URL = "https://localhost:8443/?param=valueToIgnore";
request.setRequestURI(URL);
request.setQueryString("SAMLart=ST-1234");
request.setParameter("SAMLart", "ST-1234");
final MockHttpSession session = new MockHttpSession();
request.setSession(session);
final MockHttpServletResponse response = new MockHttpServletResponse();
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
}
};
try {
f.doFilter(request, response, filterChain);
} catch (final Exception e) {
fail("The validation request should have been ignored");
}
}
}

View File

@ -20,8 +20,16 @@ package org.jasig.cas.client.validation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.jasig.cas.client.PublicTestHttpServer;
import org.jasig.cas.client.util.CommonUtils;
import org.joda.time.DateTime;
@ -30,6 +38,11 @@ import org.joda.time.Interval;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockServletContext;
/**
* @author Scott Battaglia
@ -137,7 +150,7 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes
fail(e.toString());
}
}
private Interval currentTimeRangeInterval() {
return new Interval(new DateTime(DateTimeZone.UTC).minus(5000), new DateTime(DateTimeZone.UTC).plus(200000000));
}