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

This commit is contained in:
Misagh Moayyed 2014-03-07 11:17:14 -07:00
parent b9ac92cf25
commit 71b366cbf3
10 changed files with 164 additions and 101 deletions

View File

@ -19,10 +19,12 @@
package org.jasig.cas.client.authentication;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
@ -42,11 +44,11 @@ import org.jasig.cas.client.validation.Assertion;
* <p>Please see AbstractCasFilter for additional properties.</p>
*
* @author Scott Battaglia
* @version $Revision: 11768 $ $Date: 2007-02-07 15:44:16 -0500 (Wed, 07 Feb 2007) $
* @author Misagh Moayyed
* @since 3.0
*/
public class AuthenticationFilter extends AbstractCasFilter {
/**
* The URL to the CAS Server login.
*/
@ -64,6 +66,8 @@ public class AuthenticationFilter extends AbstractCasFilter {
private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();
private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass = null;
private AuthenticationRedirectStrategy authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy();
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
@ -75,7 +79,22 @@ public class AuthenticationFilter extends AbstractCasFilter {
logger.trace("Loaded renew parameter: {}", this.renew);
setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));
logger.trace("Loaded gateway parameter: {}", this.gateway);
final String ignorePattern = getPropertyFromInitParams(filterConfig, "ignorePattern", null);
logger.trace("Loaded ignorePattern parameter: {}", ignorePattern);
final String ignoreUrlMatcherClass = getPropertyFromInitParams(filterConfig, "ignoreUrlPatternMatcherStrategyClass", null);
logger.trace("Loaded ignoreUrlPatternMatcherStrategyClass parameter: {}", ignoreUrlMatcherClass);
if (ignorePattern != null ) {
if (ignoreUrlMatcherClass != null) {
this.ignoreUrlPatternMatcherStrategyClass = ReflectUtils.newInstance(ignoreUrlMatcherClass);
} else {
this.ignoreUrlPatternMatcherStrategyClass = new RegexUrlPatternMatcherStrategy();
}
this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);
}
final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);
if (gatewayStorageClass != null) {
@ -159,4 +178,18 @@ public class AuthenticationFilter extends AbstractCasFilter {
public final void setGatewayStorage(final GatewayResolver gatewayStorage) {
this.gatewayStorage = gatewayStorage;
}
private boolean isRequestUrlExcluded(final HttpServletRequest request) {
if (this.ignoreUrlPatternMatcherStrategyClass == null) {
return false;
}
final StringBuffer urlBuffer = request.getRequestURL();
if (request.getQueryString() != null) {
urlBuffer.append("?").append(request.getQueryString());
}
final String requestUri = urlBuffer.toString();
return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri);
}
}

View File

@ -0,0 +1,38 @@
/*
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.cas.client.authentication;
/**
* A pattern matcher that looks inside the url to find the exact pattern specified.
*
* @author Misagh Moayyed
* @since 3.3.1
*/
public class ExactUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy {
private String pattern;
public boolean matches(final String url) {
return url.contains(this.pattern);
}
public void setPattern(final String pattern) {
this.pattern = pattern;
}
}

View File

@ -0,0 +1,41 @@
/*
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.cas.client.authentication;
import java.util.regex.Pattern;
/**
* A pattern matcher that looks inside the url to find the pattern,. that
* is assumed to have been specified via regular expressions syntax.
*
* @author Misagh Moayyed
* @since 3.3.1
*/
public class RegexUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy {
private Pattern pattern;
public boolean matches(final String url) {
return this.pattern.matcher(url).find();
}
public void setPattern(final String pattern) {
this.pattern = Pattern.compile(pattern);
}
}

View File

@ -0,0 +1,39 @@
/*
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.cas.client.authentication;
/**
* Defines an abstraction by which request urls can be matches against a given pattern.
*
* @author Misagh Moayyed
* @since 3.3.1
*/
public interface UrlPatternMatcherStrategy {
/**
* Execute the match between the given pattern and the url
* @param url the request url typically with query strings included
* @return true if match is successful
*/
boolean matches(final String url);
/**
* The pattern against which the url is compared
* @param pattern
*/
void setPattern(final String pattern);
}

View File

@ -18,8 +18,6 @@
*/
package org.jasig.cas.client.util;
import java.util.regex.Pattern;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -40,15 +38,6 @@ import javax.servlet.http.HttpServletResponse;
* @since 3.1
*/
public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
/**
* Enumeration that defines pattern types.
* @since 3.3.1
*/
public enum IgnorePatternTypes {
NONE,
REGEX;
}
/** Represents the constant for where the assertion will be located in memory. */
public static final String CONST_CAS_ASSERTION = "_const_cas_assertion_";
@ -58,16 +47,6 @@ 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.
* @since 3.3.1
**/
private String ignorePattern = null;
/** Denotes the pattern type.
* @since 3.3.1
*/
private IgnorePatternTypes ignorePatternType = null;
/** Sets where response.encodeUrl should be called on service urls when constructed. */
private boolean encodeServiceUrl = true;
@ -92,16 +71,6 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
logger.trace("Loading serviceParameterName property: {} ", this.serviceParameterName);
setEncodeServiceUrl(parseBoolean(getPropertyFromInitParams(filterConfig, "encodeServiceUrl", "true")));
logger.trace("Loading encodeServiceUrl property: {}", this.encodeServiceUrl);
final String ignorePattern = getPropertyFromInitParams(filterConfig, "ignorePattern", null);
if (ignorePattern != null) {
setIgnorePattern(ignorePattern);
logger.trace("Loading ignorePattern property: {}", ignorePattern);
}
setIgnorePatternType(Enum.valueOf(IgnorePatternTypes.class, getPropertyFromInitParams(filterConfig, "ignorePatternType",
IgnorePatternTypes.REGEX.name())));
logger.trace("Loading ignorePatternType property: {}", ignorePatternType);
initInternal(filterConfig);
}
@ -179,14 +148,6 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
public final String getServiceParameterName() {
return this.serviceParameterName;
}
public final void setIgnorePattern(final String patternToIgnore) {
this.ignorePattern = patternToIgnore;
}
public final void setIgnorePatternType(final IgnorePatternTypes patternType) {
this.ignorePatternType = patternType;
}
/**
* Template method to allow you to change how you retrieve the ticket.
@ -197,28 +158,4 @@ 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);
switch (this.ignorePatternType) {
case NONE:
result = requestUri.contains(this.ignorePattern);
break;
case REGEX:
result = Pattern.compile(this.ignorePattern).matcher(requestUri).find();
break;
}
}
return result;
}
}

View File

@ -190,13 +190,13 @@ 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 (!preFilter(servletRequest, servletResponse, filterChain)) {
return;
}
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final String ticket = retrieveTicketFromRequest(request);
if (CommonUtils.isNotBlank(ticket)) {
@ -254,4 +254,4 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
public final void setUseSession(final boolean useSession) {
this.useSession = useSession;
}
}
}

View File

@ -251,7 +251,7 @@ public final class AuthenticationFilterTests {
context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL);
context.addInitParameter("ignorePattern", "=valueToIgnore");
context.addInitParameter("ignorePatternType", "NONE");
context.addInitParameter("ignoreUrlPatternMatcherStrategyClass", ExactUrlPatternMatcherStrategy.class.getName());
context.addInitParameter("service", CAS_SERVICE_URL);
f.init(new MockFilterConfig(context));

View File

@ -20,19 +20,8 @@ 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;
/**
@ -65,4 +54,4 @@ public class Cas10TicketValidationFilterTests {
assertTrue(validator instanceof Cas10TicketValidator);
assertTrue(((Cas10TicketValidator) validator).isRenew());
}
}
}

View File

@ -20,19 +20,8 @@ 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;
/**
@ -65,5 +54,4 @@ public class Saml11TicketValidationFilterTests {
assertTrue(validator instanceof Saml11TicketValidator);
assertTrue(((Saml11TicketValidator) validator).isRenew());
}
}
}

View File

@ -20,10 +20,8 @@ package org.jasig.cas.client.validation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import org.jasig.cas.client.PublicTestHttpServer;
import org.jasig.cas.client.util.CommonUtils;
import org.joda.time.DateTime;
@ -139,8 +137,8 @@ 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));
}
}
}