NOJIRA
updated so that we rely on the filter instead of the listener.
This commit is contained in:
parent
de82cb0a85
commit
1031f01ee0
|
|
@ -1,88 +0,0 @@
|
|||
package org.jasig.cas.client.proxy;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
|
||||
/**
|
||||
* One of two choices for cleaning up {@link ProxyGrantingTicketStorage}.
|
||||
* You must either configure this listener in web.xml or configure
|
||||
* {@link CleanUpTimerTask} in Spring xml. Both choices perform the same
|
||||
* operation, the only difference is one is configured via the Spring
|
||||
* Framework and the other via web.xml.
|
||||
* <p>
|
||||
* See below for example web.xml configuration.
|
||||
* See {@link CleanUpTimerTask} for an example Spring xml configuration.
|
||||
* <p>
|
||||
* With this listener configured, a timer will clean up the
|
||||
* {@link ProxyGrantingTicketStorage storage}. This timer automatically
|
||||
* shuts down on webapp undeploy, so there will be no classloader leaks
|
||||
* due to an orphan thread.
|
||||
* <p>
|
||||
* Example web.xml configuration:
|
||||
* <code>
|
||||
* <listener>
|
||||
* <listener-class>org.jasig.cas.client.proxy.CleanUpListener</listener-class>
|
||||
* </listener>
|
||||
* </code>
|
||||
* <p>
|
||||
* The default time between cleanups is 60 seconds, but you can optionally
|
||||
* customize it by setting a context-param in web.xml. Example config:
|
||||
* <code>
|
||||
* <context-param>
|
||||
* <param-name>millisBetweenCleanUps</param-name>
|
||||
* <!-- 45 seconds between cleanup runs -->
|
||||
* <param-value>45000</param-value>
|
||||
* </context-param>
|
||||
* </code>
|
||||
*
|
||||
* @author Brad Cupit (brad [at] lsu {dot} edu)
|
||||
*/
|
||||
public final class CleanUpListener implements ServletContextListener {
|
||||
protected static final int DEFAULT_MILLIS_BETWEEN_CLEANUPS = 60 * 1000;
|
||||
protected static final String MILLIS_BETWEEN_CLEANUPS_INIT_PARAM = "millisBetweenCleanUps";
|
||||
private final Timer timer;
|
||||
private final TimerTask timerTask;
|
||||
|
||||
public CleanUpListener() {
|
||||
this.timer = new Timer(true);
|
||||
this.timerTask = new CleanUpTimerTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* for unit test use only
|
||||
*/
|
||||
protected CleanUpListener(final Timer timer, TimerTask timerTask ) {
|
||||
this.timer = timer;
|
||||
this.timerTask = timerTask;
|
||||
}
|
||||
|
||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||
final long millisBetweenCleanUps = getMillisBetweenCleanups(servletContextEvent.getServletContext());
|
||||
final long millisBeforeStart = millisBetweenCleanUps;
|
||||
|
||||
this.timer.schedule(timerTask, millisBeforeStart, millisBetweenCleanUps);
|
||||
}
|
||||
|
||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||
this.timer.cancel();
|
||||
}
|
||||
|
||||
protected long getMillisBetweenCleanups(ServletContext servletContext) {
|
||||
final String millisBetweenCleanUps = servletContext.getInitParameter(MILLIS_BETWEEN_CLEANUPS_INIT_PARAM);
|
||||
|
||||
if (millisBetweenCleanUps == null) {
|
||||
return DEFAULT_MILLIS_BETWEEN_CLEANUPS;
|
||||
}
|
||||
|
||||
try {
|
||||
return Long.parseLong(millisBetweenCleanUps);
|
||||
} catch (NumberFormatException exception) {
|
||||
throw new RuntimeException("The servlet context-param " + MILLIS_BETWEEN_CLEANUPS_INIT_PARAM + " must be a valid number (hint: this is usually set in web.xml)", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,37 +8,21 @@ import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
|
|||
* A {@link TimerTask} implementation which performs the
|
||||
* actual 'cleaning' by calling {@link ProxyGrantingTicketStorage#cleanUp()}.
|
||||
* <p>
|
||||
* You must configure either this TimerTask directly in Spring,
|
||||
* or the {@link CleanUpListener} (which is configured in
|
||||
* web.xml). Both choices perform the same operation, the only difference is
|
||||
* one is configured via the Spring Framework and the other via web.xml.
|
||||
* <p>
|
||||
* For an example web.xml configuration, see {@link CleanUpListener}.
|
||||
* For an example Spring xml configuration, see below:
|
||||
* <code>
|
||||
* <bean id="cleanUpTimerTask" class="org.jasig.cas.client.proxy.CleanUpTimerTask"/>
|
||||
*
|
||||
* <bean id="scheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
|
||||
* <!-- first run is 15 seconds after startup -->
|
||||
* <property name="delay" value="15000"/>
|
||||
* <!-- subsequent runs every 5 seconds -->
|
||||
* <property name="period" value="5000"/>
|
||||
* <property name="timerTask" ref="cleanUpTimerTask"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean class="org.springframework.scheduling.timer.TimerFactoryBean">
|
||||
* <property name="scheduledTimerTasks">
|
||||
* <list>
|
||||
* <ref bean="scheduledTimerTask"/>
|
||||
* </list>
|
||||
* </property>
|
||||
* </bean>
|
||||
* </code>
|
||||
* By default, the {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter} configures
|
||||
* a task that cleans up the {@link org.jasig.cas.client.proxy.ProxyGrantingTicketStorage} associated with it.
|
||||
*
|
||||
* @author Brad Cupit (brad [at] lsu {dot} edu)
|
||||
* @version $Revision$ $Date$
|
||||
* @since 3.1.6
|
||||
*/
|
||||
public final class CleanUpTimerTask extends TimerTask {
|
||||
|
||||
private final ProxyGrantingTicketStorage proxyGrantingTicketStorage;
|
||||
|
||||
public CleanUpTimerTask(final ProxyGrantingTicketStorage proxyGrantingTicketStorage) {
|
||||
this.proxyGrantingTicketStorage = proxyGrantingTicketStorage;
|
||||
}
|
||||
public void run() {
|
||||
Cas20ProxyReceivingTicketValidationFilter.getProxyGrantingTicketStorage().cleanUp();
|
||||
this.proxyGrantingTicketStorage.cleanUp();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,13 +63,18 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
|
|||
init();
|
||||
}
|
||||
|
||||
/** Controls the ordering of filter initialization and checking by defining a method that runs before the init. */
|
||||
/** Controls the ordering of filter initialization and checking by defining a method that runs before the init.
|
||||
* @param filterConfig the original filter configuration.
|
||||
* @throws ServletException if there is a problem.
|
||||
*
|
||||
*/
|
||||
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
|
||||
// template method
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization method. Called by Filter's init method or by Spring.
|
||||
* Initialization method. Called by Filter's init method or by Spring. Similar in concept to the InitializingBean interface's
|
||||
* afterPropertiesSet();
|
||||
*/
|
||||
public void init() {
|
||||
CommonUtils.assertNotNull(this.artifactParameterName, "artifactParameterName cannot be null.");
|
||||
|
|
@ -77,7 +82,8 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
|
|||
CommonUtils.assertTrue(CommonUtils.isNotEmpty(this.serverName) || CommonUtils.isNotEmpty(this.service), "serverName or service must be set.");
|
||||
}
|
||||
|
||||
public final void destroy() {
|
||||
// empty implementation as most filters won't need this.
|
||||
public void destroy() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,4 +183,8 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
|
|||
public final void setUseSession(final boolean useSession) {
|
||||
this.useSession = useSession;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,7 @@
|
|||
package org.jasig.cas.client.validation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
|
@ -21,48 +16,58 @@ import javax.servlet.ServletResponse;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jasig.cas.client.proxy.Cas20ProxyRetriever;
|
||||
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
|
||||
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
|
||||
import org.jasig.cas.client.proxy.CleanUpListener;
|
||||
import org.jasig.cas.client.proxy.*;
|
||||
import org.jasig.cas.client.util.CommonUtils;
|
||||
|
||||
/**
|
||||
* Creates either a CAS20ProxyTicketValidator or a CAS20ServiceTicketValidator depending on whether any of the
|
||||
* proxy parameters are set.
|
||||
* <p>
|
||||
* This filter can also pass additional parameteres to the ticket validator. Any init parameter not included in the
|
||||
* This filter can also pass additional parameters to the ticket validator. Any init parameter not included in the
|
||||
* reserved list {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter#RESERVED_INIT_PARAMS}.
|
||||
*
|
||||
* @author Scott Battaglia
|
||||
* @author Brad Cupit (brad [at] lsu {dot} edu)
|
||||
* @version $Revision$ $Date$
|
||||
* @since 3.1
|
||||
*
|
||||
*/
|
||||
public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketValidationFilter {
|
||||
|
||||
private static final String[] RESERVED_INIT_PARAMS = new String[] {"proxyReceptorUrl", "acceptAnyProxy", "allowedProxyChains", "casServerUrlPrefix", "proxyCallbackUrl", "renew", "exceptionOnValidationFailure", "redirectAfterValidation", "useSession", "serverName", "service", "artifactParameterName", "serviceParameterName", "encodeServiceUrl"};
|
||||
private static final String[] RESERVED_INIT_PARAMS = new String[] {"proxyReceptorUrl", "acceptAnyProxy", "allowedProxyChains", "casServerUrlPrefix", "proxyCallbackUrl", "renew", "exceptionOnValidationFailure", "redirectAfterValidation", "useSession", "serverName", "service", "artifactParameterName", "serviceParameterName", "encodeServiceUrl", "millisBetweenCleanUps"};
|
||||
|
||||
private static final int DEFAULT_MILLIS_BETWEEN_CLEANUPS = 60 * 1000;
|
||||
|
||||
/**
|
||||
* The URL to send to the CAS server as the URL that will process proxying requests on the CAS client.
|
||||
*/
|
||||
private String proxyReceptorUrl;
|
||||
|
||||
private Timer timer;
|
||||
|
||||
private TimerTask timerTask;
|
||||
|
||||
private int millisBetweenCleanUps;
|
||||
|
||||
/**
|
||||
* Storage location of ProxyGrantingTickets and Proxy Ticket IOUs.
|
||||
*/
|
||||
private static ProxyGrantingTicketStorage proxyGrantingTicketStorage = new ProxyGrantingTicketStorageImpl();
|
||||
private ProxyGrantingTicketStorage proxyGrantingTicketStorage = new ProxyGrantingTicketStorageImpl();
|
||||
|
||||
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
|
||||
super.initInternal(filterConfig);
|
||||
setProxyReceptorUrl(getPropertyFromInitParams(filterConfig, "proxyReceptorUrl", null));
|
||||
|
||||
log.trace("Setting proxyReceptorUrl parameter: " + this.proxyReceptorUrl);
|
||||
this.millisBetweenCleanUps = Integer.parseInt(getPropertyFromInitParams(filterConfig, "millisBetweenCleanUps", Integer.toString(DEFAULT_MILLIS_BETWEEN_CLEANUPS)));
|
||||
}
|
||||
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
CommonUtils.assertNotNull(proxyGrantingTicketStorage, "proxyGrantingTicketStorage cannot be null.");
|
||||
this.timer = new Timer(true);
|
||||
this.timerTask = new CleanUpTimerTask(this.proxyGrantingTicketStorage);
|
||||
this.timer.schedule(this.timerTask, this.millisBetweenCleanUps, this.millisBetweenCleanUps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,6 +123,11 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
return (List) editor.getValue();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
this.timer.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* This processes the ProxyReceptor request before the ticket validation code executes.
|
||||
*/
|
||||
|
|
@ -138,17 +148,16 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
|
|||
public final void setProxyReceptorUrl(final String proxyReceptorUrl) {
|
||||
this.proxyReceptorUrl = proxyReceptorUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static getter so {@link CleanUpListener} has some way of retrieving
|
||||
* the actual storage. This relies on the fact that this class (the Filter)
|
||||
* will only be instantiated once per webapp.
|
||||
*/
|
||||
public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() {
|
||||
return proxyGrantingTicketStorage;
|
||||
}
|
||||
|
||||
public void setProxyGrantingTicketStorage(ProxyGrantingTicketStorage storage) {
|
||||
public void setProxyGrantingTicketStorage(final ProxyGrantingTicketStorage storage) {
|
||||
proxyGrantingTicketStorage = storage;
|
||||
}
|
||||
|
||||
public void setTimer(final Timer timer) {
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
public void setTimerTask(final TimerTask timerTask) {
|
||||
this.timerTask = timerTask;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,8 +86,7 @@ public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator
|
|||
final Map authenticationAttributes = new HashMap();
|
||||
authenticationAttributes.put("samlAuthenticationStatement::authMethod", authenticationStatement.getAuthMethod());
|
||||
|
||||
final Assertion casAssertion = new AssertionImpl(principal, authenticationAttributes);
|
||||
return casAssertion;
|
||||
return new AssertionImpl(principal, authenticationAttributes);
|
||||
}
|
||||
} catch (final SAMLException e) {
|
||||
throw new TicketValidationException(e);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ import org.springframework.mock.web.MockServletContext;
|
|||
*/
|
||||
public class CleanUpListenerTest extends TestCase {
|
||||
private final Timer defaultTimer = new Timer(true);
|
||||
/*
|
||||
private final CleanUpTimerTask defaultTimerTask = new CleanUpTimerTask();
|
||||
|
||||
|
||||
|
||||
public void testStartsThreadAtStartup() throws Exception {
|
||||
final MethodFlag scheduleMethodFlag = new MethodFlag();
|
||||
|
||||
|
|
@ -119,36 +121,5 @@ public class CleanUpListenerTest extends TestCase {
|
|||
// expected, test passes
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit test helper class to mock a real {@link ServletContextEvent}
|
||||
*
|
||||
* @author Brad Cupit (brad [at] lsu {dot} edu)
|
||||
*/
|
||||
private static final class TestServletContextEvent extends ServletContextEvent {
|
||||
private TestServletContextEvent(long millisBetweenCleanUps) {
|
||||
super(new TestServletContext(millisBetweenCleanUps));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit test helper class to mock a real {@link ServletContext}
|
||||
*
|
||||
* @author Brad Cupit (brad [at] lsu {dot} edu)
|
||||
*/
|
||||
private static final class TestServletContext extends MockServletContext {
|
||||
private final long millisBetweenCleanUps;
|
||||
|
||||
public TestServletContext(long millisBetweenCleanUps) {
|
||||
this.millisBetweenCleanUps = millisBetweenCleanUps;
|
||||
}
|
||||
|
||||
public String getInitParameter(String name) {
|
||||
if (name.equals(CleanUpListener.MILLIS_BETWEEN_CLEANUPS_INIT_PARAM)) {
|
||||
return Long.toString(millisBetweenCleanUps);
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected init param requested: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ import junit.framework.TestCase;
|
|||
public class CleanUpTimerTaskTest extends TestCase {
|
||||
|
||||
public void testRun() throws Exception {
|
||||
TimerTask timerTask = new CleanUpTimerTask();
|
||||
|
||||
ProxyGrantingTicketStorageTestImpl storage = new ProxyGrantingTicketStorageTestImpl();
|
||||
final ProxyGrantingTicketStorageTestImpl storage = new ProxyGrantingTicketStorageTestImpl();
|
||||
new Cas20ProxyReceivingTicketValidationFilter().setProxyGrantingTicketStorage(storage);
|
||||
|
||||
|
||||
final TimerTask timerTask = new CleanUpTimerTask(storage);
|
||||
|
||||
timerTask.run();
|
||||
assertTrue(storage.cleanUpWasCalled());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@ import junit.framework.TestCase;
|
|||
* @author Brad Cupit (brad [at] lsu {dot} edu)
|
||||
*/
|
||||
public class Cas20ProxyReceivingTicketValidationFilterTest extends TestCase {
|
||||
public void testHasDefaultStorage() throws Exception {
|
||||
assertNotNull(Cas20ProxyReceivingTicketValidationFilter.getProxyGrantingTicketStorage());
|
||||
}
|
||||
|
||||
public void testThrowsForNullStorage() throws Exception {
|
||||
Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
|
||||
|
|
|
|||
Loading…
Reference in New Issue