Merge pull request #86 from battags/CASC-200-rebasefail

CASC-200 Introduce Mechanism to Indicate Method of Configuration
This commit is contained in:
Scott 2014-12-07 12:12:56 -05:00
commit b76ede66fb
33 changed files with 943 additions and 283 deletions

View File

@ -0,0 +1,33 @@
package org.jasig.cas.client;
/**
* Simple enumeration to hold/capture some of the standard request parameters used by the various protocols.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public enum Protocol {
CAS1("ticket", "service"), CAS2(CAS1), SAML11("SAMLart", "TARGET");
private final String artifactParameterName;
private final String serviceParameterName;
private Protocol(final String artifactParameterName, final String serviceParameterName) {
this.artifactParameterName = artifactParameterName;
this.serviceParameterName = serviceParameterName;
}
private Protocol(final Protocol protocol) {
this(protocol.getArtifactParameterName(), protocol.getServiceParameterName());
}
public String getArtifactParameterName() {
return this.artifactParameterName;
}
public String getServiceParameterName() {
return this.serviceParameterName;
}
}

View File

@ -27,6 +27,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
@ -79,22 +81,24 @@ public class AuthenticationFilter extends AbstractCasFilter {
PATTERN_MATCHER_TYPES.put("REGEX", RegexUrlPatternMatcherStrategy.class);
PATTERN_MATCHER_TYPES.put("EXACT", ExactUrlPatternMatcherStrategy.class);
}
public AuthenticationFilter() {
this(Protocol.CAS2);
}
protected AuthenticationFilter(final Protocol protocol) {
super(protocol);
}
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
if (!isIgnoreInitConfiguration()) {
super.initInternal(filterConfig);
setCasServerLoginUrl(getPropertyFromInitParams(filterConfig, "casServerLoginUrl", null));
logger.trace("Loaded CasServerLoginUrl parameter: {}", this.casServerLoginUrl);
setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
logger.trace("Loaded renew parameter: {}", this.renew);
setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));
logger.trace("Loaded gateway parameter: {}", this.gateway);
setCasServerLoginUrl(getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL));
setRenew(getBoolean(ConfigurationKeys.RENEW));
setGateway(getBoolean(ConfigurationKeys.GATEWAY));
final String ignorePattern = getPropertyFromInitParams(filterConfig, "ignorePattern", null);
logger.trace("Loaded ignorePattern parameter: {}", ignorePattern);
final String ignoreUrlPatternType = getPropertyFromInitParams(filterConfig, "ignoreUrlPatternType", "REGEX");
logger.trace("Loaded ignoreUrlPatternType parameter: {}", ignoreUrlPatternType);
final String ignorePattern = getString(ConfigurationKeys.IGNORE_PATTERN);
final String ignoreUrlPatternType = getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE);
if (ignorePattern != null) {
final Class<? extends UrlPatternMatcherStrategy> ignoreUrlMatcherClass = PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType);
@ -113,14 +117,13 @@ public class AuthenticationFilter extends AbstractCasFilter {
}
}
final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);
final Class<? extends GatewayResolver> gatewayStorageClass = getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS);
if (gatewayStorageClass != null) {
this.gatewayStorage = ReflectUtils.newInstance(gatewayStorageClass);
setGatewayStorage(ReflectUtils.newInstance(gatewayStorageClass));
}
final String authenticationRedirectStrategyClass = getPropertyFromInitParams(filterConfig,
"authenticationRedirectStrategyClass", null);
final Class<? extends AuthenticationRedirectStrategy> authenticationRedirectStrategyClass = getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS);
if (authenticationRedirectStrategyClass != null) {
this.authenticationRedirectStrategy = ReflectUtils.newInstance(authenticationRedirectStrategyClass);
@ -175,7 +178,7 @@ public class AuthenticationFilter extends AbstractCasFilter {
logger.debug("Constructed service url: {}", modifiedServiceUrl);
final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl,
getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
logger.debug("redirecting to \"{}\"", urlToRedirectTo);
this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);

View File

@ -18,13 +18,12 @@
*/
package org.jasig.cas.client.authentication;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.jasig.cas.client.Protocol;
/**
* Extension to the default Authentication filter that sets the required SAML1.1 artifact parameter name and service parameter name.
* <p>
* Note, as of 3.3, the final keyword was removed to allow you to override the method to retrieve tickets, per CASC-154s
* Note, as of 3.3, the final keyword was removed to allow you to override the method to retrieve tickets, per CASC-154
*
* @author Scott Battaglia
* @since 3.1.12
@ -32,13 +31,7 @@ import javax.servlet.ServletException;
*/
public class Saml11AuthenticationFilter extends AuthenticationFilter {
protected final void initInternal(final FilterConfig filterConfig) throws ServletException {
super.initInternal(filterConfig);
logger.warn("SAML1.1 compliance requires the [artifactParameterName] and [serviceParameterName] to be set to specified values.");
logger.warn("This filter will overwrite any user-provided values (if any are provided)");
setArtifactParameterName("SAMLart");
setServiceParameterName("TARGET");
private Saml11AuthenticationFilter() {
super(Protocol.SAML11);
}
}

View File

@ -0,0 +1,95 @@
package org.jasig.cas.client.configuration;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class to provide most of the boiler-plate code (i.e. checking for proper values, returning defaults, etc.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public abstract class BaseConfigurationStrategy implements ConfigurationStrategy {
protected final Logger logger = LoggerFactory.getLogger(getClass());
public final boolean getBoolean(final ConfigurationKey<Boolean> configurationKey) {
return getValue(configurationKey, new Parser<Boolean>() {
public Boolean parse(final String value) {
return BooleanUtils.toBoolean(value);
}
});
}
public final long getLong(final ConfigurationKey<Long> configurationKey) {
return getValue(configurationKey, new Parser<Long>() {
public Long parse(final String value) {
return NumberUtils.toLong(value, configurationKey.getDefaultValue());
}
});
}
public final int getInt(final ConfigurationKey<Integer> configurationKey) {
return getValue(configurationKey, new Parser<Integer>() {
public Integer parse(final String value) {
return NumberUtils.toInt(value, configurationKey.getDefaultValue());
}
});
}
public final String getString(final ConfigurationKey<String> configurationKey) {
return getValue(configurationKey, new Parser<String>() {
public String parse(final String value) {
return value;
}
});
}
public <T> Class<? extends T> getClass(final ConfigurationKey<Class<? extends T>> configurationKey) {
return getValue(configurationKey, new Parser<Class<? extends T>>() {
public Class<? extends T> parse(final String value) {
try {
return ReflectUtils.loadClass(value);
} catch (final IllegalArgumentException e) {
return configurationKey.getDefaultValue();
}
}
});
}
private <T> T getValue(final ConfigurationKey<T> configurationKey, final Parser<T> parser) {
final String value = getWithCheck(configurationKey);
if (CommonUtils.isBlank(value)) {
logger.trace("No value found for property {}, returning default {}", configurationKey.getName(), configurationKey.getDefaultValue());
return configurationKey.getDefaultValue();
} else {
logger.trace("Loaded property {} with value {}", configurationKey.getName(), configurationKey.getDefaultValue());
}
return parser.parse(value);
}
private String getWithCheck(final ConfigurationKey configurationKey) {
CommonUtils.assertNotNull(configurationKey, "configurationKey cannot be null");
return get(configurationKey);
}
/**
* Retrieve the String value for this key. Returns null if there is no value.
*
* @param configurationKey the key to retrieve. MUST NOT BE NULL.
* @return the String if its found, null otherwise.
*/
protected abstract String get(ConfigurationKey configurationKey);
private interface Parser<T> {
T parse(String value);
}
}

View File

@ -0,0 +1,45 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.util.CommonUtils;
/**
* Holder class to represent a particular configuration key and its optional default value.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class ConfigurationKey<E> {
private final String name;
private final E defaultValue;
public ConfigurationKey(final String name) {
this(name, null);
}
public ConfigurationKey(final String name, final E defaultValue) {
CommonUtils.assertNotNull(name, "name must not be null.");
this.name = name;
this.defaultValue = defaultValue;
}
/**
* The referencing name of the configuration key (i.e. what you would use to look it up in your configuration strategy)
*
* @return the name. MUST NOT BE NULL.
*/
public String getName() {
return this.name;
}
/**
* The (optional) default value to use when this configuration key is not set. If a value is provided it should be used. A <code>null</code> value indicates that there is no default.
*
* @return the default value or null.
*/
public E getDefaultValue() {
return this.defaultValue;
}
}

View File

@ -0,0 +1,58 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.authentication.AuthenticationRedirectStrategy;
import org.jasig.cas.client.authentication.DefaultGatewayResolverImpl;
import org.jasig.cas.client.authentication.GatewayResolver;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import javax.net.ssl.HostnameVerifier;
/**
* Holder interface for all known configuration keys.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public interface ConfigurationKeys {
ConfigurationKey<String> ARTIFACT_PARAMETER_NAME = new ConfigurationKey<String>("artifactParameterName", Protocol.CAS2.getArtifactParameterName());
ConfigurationKey<String> SERVER_NAME = new ConfigurationKey<String>("serverName", null);
ConfigurationKey<String> SERVICE = new ConfigurationKey<String>("service");
ConfigurationKey<Boolean> RENEW = new ConfigurationKey<Boolean>("renew", Boolean.FALSE);
ConfigurationKey<String> LOGOUT_PARAMETER_NAME = new ConfigurationKey<String>("logoutParameterName", "logoutRequest");
ConfigurationKey<Boolean> ARTIFACT_PARAMETER_OVER_POST = new ConfigurationKey<Boolean>("artifactParameterOverPost", Boolean.FALSE);
ConfigurationKey<Boolean> EAGERLY_CREATE_SESSIONS = new ConfigurationKey<Boolean>("eagerlyCreateSessions", Boolean.TRUE);
ConfigurationKey<Boolean> ENCODE_SERVICE_URL = new ConfigurationKey<Boolean>("encodeServiceUrl", Boolean.TRUE);
ConfigurationKey<String> SSL_CONFIG_FILE = new ConfigurationKey<String>("sslConfigFile", null);
ConfigurationKey<String> ROLE_ATTRIBUTE = new ConfigurationKey<String>("roleAttribute", null);
ConfigurationKey<Boolean> IGNORE_CASE = new ConfigurationKey<Boolean>("ignoreCase", Boolean.FALSE);
ConfigurationKey<String> CAS_SERVER_LOGIN_URL = new ConfigurationKey<String>("casServerLoginUrl", null);
ConfigurationKey<Boolean> GATEWAY = new ConfigurationKey<Boolean>("gateway", Boolean.FALSE);
ConfigurationKey<Class<? extends AuthenticationRedirectStrategy>> AUTHENTICATION_REDIRECT_STRATEGY_CLASS = new ConfigurationKey<Class<? extends AuthenticationRedirectStrategy>>("authenticationRedirectStrategyClass", null);
ConfigurationKey<Class<? extends GatewayResolver>> GATEWAY_STORAGE_CLASS = new ConfigurationKey<Class<? extends GatewayResolver>>("gatewayStorageClass", DefaultGatewayResolverImpl.class);
ConfigurationKey<String> CAS_SERVER_URL_PREFIX = new ConfigurationKey<String>("casServerUrlPrefix", null);
ConfigurationKey<String> ENCODING = new ConfigurationKey<String>("encoding", null);
ConfigurationKey<Long> TOLERANCE = new ConfigurationKey<Long>("tolerance", 1000L);
ConfigurationKey<Boolean> DISABLE_XML_SCHEMA_VALIDATION = new ConfigurationKey<Boolean>("disableXmlSchemaValidation", Boolean.FALSE);
ConfigurationKey<String> IGNORE_PATTERN = new ConfigurationKey<String>("ignorePattern", null);
ConfigurationKey<String> IGNORE_URL_PATTERN_TYPE = new ConfigurationKey<String>("ignoreUrlPatternType", "REGEX");
ConfigurationKey<Class<? extends HostnameVerifier>> HOSTNAME_VERIFIER = new ConfigurationKey<Class<? extends HostnameVerifier>>("hostnameVerifier", null);
ConfigurationKey<String> HOSTNAME_VERIFIER_CONFIG = new ConfigurationKey<String>("hostnameVerifierConfig", null);
ConfigurationKey<Boolean> EXCEPTION_ON_VALIDATION_FAILURE = new ConfigurationKey<Boolean>("exceptionOnValidationFailure", Boolean.TRUE);
ConfigurationKey<Boolean> REDIRECT_AFTER_VALIDATION = new ConfigurationKey<Boolean>("redirectAfterValidation", Boolean.TRUE);
ConfigurationKey<Boolean> USE_SESSION = new ConfigurationKey<Boolean>("useSession", Boolean.TRUE);
ConfigurationKey<String> SECRET_KEY = new ConfigurationKey<String>("secretKey", null);
ConfigurationKey<String> CIPHER_ALGORITHM = new ConfigurationKey<String>("cipherAlgorithm", "DESede");
ConfigurationKey<String> PROXY_RECEPTOR_URL = new ConfigurationKey<String>("proxyReceptorUrl", null);
ConfigurationKey<Class<? extends ProxyGrantingTicketStorage>> PROXY_GRANTING_TICKET_STORAGE_CLASS = new ConfigurationKey<Class<? extends ProxyGrantingTicketStorage>>("proxyGrantingTicketStorageClass", ProxyGrantingTicketStorageImpl.class);
ConfigurationKey<Integer> MILLIS_BETWEEN_CLEAN_UPS = new ConfigurationKey<Integer>("millisBetweenCleanUps", 60000);
ConfigurationKey<Boolean> ACCEPT_ANY_PROXY = new ConfigurationKey<Boolean>("acceptAnyProxy", Boolean.FALSE);
ConfigurationKey<String> ALLOWED_PROXY_CHAINS = new ConfigurationKey<String>("allowedProxyChains", null);
ConfigurationKey<Class<? extends Cas20ServiceTicketValidator>> TICKET_VALIDATOR_CLASS = new ConfigurationKey<Class<? extends Cas20ServiceTicketValidator>>("ticketValidatorClass", null);
ConfigurationKey<String> PROXY_CALLBACK_URL = new ConfigurationKey<String>("proxyCallbackUrl", null);
ConfigurationKey<String> FRONT_LOGOUT_PARAMETER_NAME = new ConfigurationKey<String>("frontLogoutParameterName", "SAMLRequest");
ConfigurationKey<String> RELAY_STATE_PARAMETER_NAME = new ConfigurationKey<String>("relayStateParameterName", "RelayState");
}

View File

@ -0,0 +1,61 @@
package org.jasig.cas.client.configuration;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Abstraction to allow for pluggable methods for retrieving filter configuration.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public interface ConfigurationStrategy {
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
boolean getBoolean(ConfigurationKey<Boolean> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
String getString(ConfigurationKey<String> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
long getLong(ConfigurationKey<Long> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
int getInt(ConfigurationKey<Integer> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
<T> Class<? extends T> getClass(ConfigurationKey<Class<? extends T>> configurationKey);
/**
* Initializes the strategy. This must be called before calling any of the "get" methods.
*
* @param filterConfig the filter configuration object.
* @param filterClazz the filter
*/
void init(FilterConfig filterConfig, Class<? extends Filter> filterClazz);
}

View File

@ -0,0 +1,55 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.util.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Enumeration to map simple names to the underlying classes so that deployers can reference the simple name in the
* <code>web.xml</code> instead of the fully qualified class name.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public enum ConfigurationStrategyName {
DEFAULT(LegacyConfigurationStrategyImpl.class), JNDI(JndiConfigurationStrategyImpl.class), WEB_XML(WebXmlConfigurationStrategyImpl.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationStrategyName.class);
private final Class<? extends ConfigurationStrategy> configurationStrategyClass;
private ConfigurationStrategyName(final Class<? extends ConfigurationStrategy> configurationStrategyClass) {
this.configurationStrategyClass = configurationStrategyClass;
}
/**
* Static helper method that will resolve a simple string to either an enum value or a {@link org.jasig.cas.client.configuration.ConfigurationStrategy} class.
*
* @param value the value to attempt to resolve.
* @return the underlying class that this maps to (either via simple name or fully qualified class name).
*/
public static Class<? extends ConfigurationStrategy> resolveToConfigurationStrategy(final String value) {
if (CommonUtils.isBlank(value)) {
return DEFAULT.configurationStrategyClass;
}
for (final ConfigurationStrategyName csn : values()) {
if (csn.name().equalsIgnoreCase(value)) {
return csn.configurationStrategyClass;
}
}
try {
final Class<?> clazz = Class.forName(value);
if (clazz.isAssignableFrom(ConfigurationStrategy.class)) {
return (Class<? extends ConfigurationStrategy>) clazz;
}
} catch (final ClassNotFoundException e) {
LOGGER.error("Unable to locate strategy {} by name or class name. Using default strategy instead.", value, e);
}
return DEFAULT.configurationStrategyClass;
}
}

View File

@ -0,0 +1,75 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.util.CommonUtils;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Loads configuration information from JNDI, using the <code>defaultValue</code> if it can't.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public class JndiConfigurationStrategyImpl extends BaseConfigurationStrategy {
private static final String ENVIRONMENT_PREFIX = "java:comp/env/cas/";
private final String environmentPrefix;
private InitialContext context;
private String simpleFilterName;
public JndiConfigurationStrategyImpl() {
this(ENVIRONMENT_PREFIX);
}
public JndiConfigurationStrategyImpl(final String environmentPrefix) {
this.environmentPrefix = environmentPrefix;
}
@Override
protected final String get(final ConfigurationKey configurationKey) {
if (context == null) {
return null;
}
final String propertyName = configurationKey.getName();
final String filterValue = loadFromContext(context, this.environmentPrefix + this.simpleFilterName + "/" + propertyName);
if (CommonUtils.isNotBlank(filterValue)) {
logger.info("Property [{}] loaded from JNDI Filter Specific Property with value [{}]", propertyName, filterValue);
return filterValue;
}
final String rootValue = loadFromContext(context, this.environmentPrefix + propertyName);
if (CommonUtils.isNotBlank(rootValue)) {
logger.info("Property [{}] loaded from JNDI with value [{}]", propertyName, rootValue);
return rootValue;
}
return null;
}
private String loadFromContext(final InitialContext context, final String path) {
try {
return (String) context.lookup(path);
} catch (final NamingException e) {
return null;
}
}
public final void init(final FilterConfig filterConfig, final Class<? extends Filter> clazz) {
this.simpleFilterName = clazz.getSimpleName();
try {
this.context = new InitialContext();
} catch (final NamingException e) {
logger.error("Unable to create InitialContext. No properties can be loaded via JNDI.", e);
}
}
}

View File

@ -0,0 +1,35 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.util.CommonUtils;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Replicates the original behavior by checking the {@link org.jasig.cas.client.configuration.WebXmlConfigurationStrategyImpl} first, and then
* the {@link org.jasig.cas.client.configuration.JndiConfigurationStrategyImpl} before using the <code>defaultValue</code>.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class LegacyConfigurationStrategyImpl extends BaseConfigurationStrategy {
private final WebXmlConfigurationStrategyImpl webXmlConfigurationStrategy = new WebXmlConfigurationStrategyImpl();
private final JndiConfigurationStrategyImpl jndiConfigurationStrategy = new JndiConfigurationStrategyImpl();
public void init(FilterConfig filterConfig, Class<? extends Filter> filterClazz) {
this.webXmlConfigurationStrategy.init(filterConfig, filterClazz);
this.jndiConfigurationStrategy.init(filterConfig, filterClazz);
}
protected String get(final ConfigurationKey key) {
final String value1 = this.webXmlConfigurationStrategy.get(key);
if (CommonUtils.isNotBlank(value1)) {
return value1;
}
return this.jndiConfigurationStrategy.get(key);
}
}

View File

@ -0,0 +1,42 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.util.CommonUtils;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Implementation of the {@link org.jasig.cas.client.configuration.ConfigurationStrategy} that first checks the {@link javax.servlet.FilterConfig} and
* then checks the {@link javax.servlet.ServletContext}, ultimately falling back to the <code>defaultValue</code>.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class WebXmlConfigurationStrategyImpl extends BaseConfigurationStrategy {
private FilterConfig filterConfig;
protected String get(final ConfigurationKey configurationKey) {
final String value = this.filterConfig.getInitParameter(configurationKey.getName());
if (CommonUtils.isNotBlank(value)) {
CommonUtils.assertFalse(ConfigurationKeys.RENEW.equals(configurationKey), "Renew MUST be specified via context parameter or JNDI environment to avoid misconfiguration.");
logger.info("Property [{}] loaded from FilterConfig.getInitParameter with value [{}]", configurationKey, value);
return value;
}
final String value2 = filterConfig.getServletContext().getInitParameter(configurationKey.getName());
if (CommonUtils.isNotBlank(value2)) {
logger.info("Property [{}] loaded from ServletContext.getInitParameter with value [{}]", configurationKey,
value2);
return value2;
}
return null;
}
public void init(final FilterConfig filterConfig, final Class<? extends Filter> clazz) {
this.filterConfig = filterConfig;
}
}

View File

@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
@ -50,12 +51,16 @@ import org.jasig.cas.client.util.CommonUtils;
*/
public final class Servlet3AuthenticationFilter extends AbstractCasFilter {
public Servlet3AuthenticationFilter() {
super(Protocol.CAS2);
}
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final HttpSession session = request.getSession();
final String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());
final String ticket = CommonUtils.safeGetParameter(request, getProtocol().getArtifactParameterName());
if (session != null && session.getAttribute(CONST_CAS_ASSERTION) == null && ticket != null) {
try {

View File

@ -18,6 +18,8 @@
*/
package org.jasig.cas.client.proxy;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
@ -36,11 +38,9 @@ import javax.crypto.spec.DESedeKeySpec;
*/
public abstract class AbstractEncryptedProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage {
public static final String DEFAULT_ENCRYPTION_ALGORITHM = "DESede";
private Key key;
private String cipherAlgorithm = DEFAULT_ENCRYPTION_ALGORITHM;
private String cipherAlgorithm = ConfigurationKeys.CIPHER_ALGORITHM.getDefaultValue();
public final void setSecretKey(final String key) throws NoSuchAlgorithmException, InvalidKeyException,
InvalidKeySpecException {

View File

@ -22,8 +22,10 @@ import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractConfigurationFilter;
/**
@ -40,20 +42,15 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter {
private AtomicBoolean handlerInitialized = new AtomicBoolean(false);
public void init(final FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
if (!isIgnoreInitConfiguration()) {
HANDLER.setArtifactParameterName(getPropertyFromInitParams(filterConfig, "artifactParameterName",
SingleSignOutHandler.DEFAULT_ARTIFACT_PARAMETER_NAME));
HANDLER.setLogoutParameterName(getPropertyFromInitParams(filterConfig, "logoutParameterName",
SingleSignOutHandler.DEFAULT_LOGOUT_PARAMETER_NAME));
HANDLER.setFrontLogoutParameterName(getPropertyFromInitParams(filterConfig, "frontLogoutParameterName",
SingleSignOutHandler.DEFAULT_FRONT_LOGOUT_PARAMETER_NAME));
HANDLER.setRelayStateParameterName(getPropertyFromInitParams(filterConfig, "relayStateParameterName",
SingleSignOutHandler.DEFAULT_RELAY_STATE_PARAMETER_NAME));
HANDLER.setCasServerUrlPrefix(getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", ""));
HANDLER.setArtifactParameterOverPost(parseBoolean(getPropertyFromInitParams(filterConfig,
"artifactParameterOverPost", "false")));
HANDLER.setEagerlyCreateSessions(parseBoolean(getPropertyFromInitParams(filterConfig,
"eagerlyCreateSessions", "true")));
setArtifactParameterName(getString(ConfigurationKeys.ARTIFACT_PARAMETER_NAME));
setLogoutParameterName(getString(ConfigurationKeys.LOGOUT_PARAMETER_NAME));
setFrontLogoutParameterName(getString(ConfigurationKeys.FRONT_LOGOUT_PARAMETER_NAME));
setRelayStateParameterName(getString(ConfigurationKeys.RELAY_STATE_PARAMETER_NAME));
setCasServerUrlPrefix(getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX));
HANDLER.setArtifactParameterOverPost(getBoolean(ConfigurationKeys.ARTIFACT_PARAMETER_OVER_POST));
HANDLER.setEagerlyCreateSessions(getBoolean(ConfigurationKeys.EAGERLY_CREATE_SESSIONS));
}
HANDLER.init();
handlerInitialized.set(true);

View File

@ -29,6 +29,8 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.XmlUtils;
import org.slf4j.Logger;
@ -44,11 +46,6 @@ import org.slf4j.LoggerFactory;
*/
public final class SingleSignOutHandler {
public final static String DEFAULT_ARTIFACT_PARAMETER_NAME = "ticket";
public final static String DEFAULT_LOGOUT_PARAMETER_NAME = "logoutRequest";
public final static String DEFAULT_FRONT_LOGOUT_PARAMETER_NAME = "SAMLRequest";
public final static String DEFAULT_RELAY_STATE_PARAMETER_NAME = "RelayState";
private final static int DECOMPRESSION_FACTOR = 10;
/** Logger instance */
@ -58,16 +55,16 @@ public final class SingleSignOutHandler {
private SessionMappingStorage sessionMappingStorage = new HashMapBackedSessionMappingStorage();
/** The name of the artifact parameter. This is used to capture the session identifier. */
private String artifactParameterName = DEFAULT_ARTIFACT_PARAMETER_NAME;
private String artifactParameterName = Protocol.CAS2.getArtifactParameterName();
/** Parameter name that stores logout request for back channel SLO */
private String logoutParameterName = DEFAULT_LOGOUT_PARAMETER_NAME;
private String logoutParameterName = ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue();
/** Parameter name that stores logout request for front channel SLO */
private String frontLogoutParameterName = DEFAULT_FRONT_LOGOUT_PARAMETER_NAME;
private String frontLogoutParameterName = ConfigurationKeys.FRONT_LOGOUT_PARAMETER_NAME.getDefaultValue();
/** Parameter name that stores the state of the CAS server webflow for the callback */
private String relayStateParameterName = DEFAULT_RELAY_STATE_PARAMETER_NAME;
private String relayStateParameterName = ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue();
/** The prefix url of the CAS server */
private String casServerUrlPrefix = "";

View File

@ -18,6 +18,9 @@
*/
package org.jasig.cas.client.util;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -42,12 +45,8 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
/** Represents the constant for where the assertion will be located in memory. */
public static final String CONST_CAS_ASSERTION = "_const_cas_assertion_";
/** Defines the parameter to look for for the artifact. */
private String artifactParameterName = "ticket";
private Protocol protocol;
/** Defines the parameter to look for for the service. */
private String serviceParameterName = "service";
/** Sets where response.encodeUrl should be called on service urls when constructed. */
private boolean encodeServiceUrl = true;
@ -59,18 +58,16 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
/** The exact url of the service. */
private String service;
protected AbstractCasFilter(final Protocol protocol) {
this.protocol = protocol;
}
public final void init(final FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
if (!isIgnoreInitConfiguration()) {
setServerName(getPropertyFromInitParams(filterConfig, "serverName", null));
logger.trace("Loading serverName property: {}", this.serverName);
setService(getPropertyFromInitParams(filterConfig, "service", null));
logger.trace("Loading service property: {}", this.service);
setArtifactParameterName(getPropertyFromInitParams(filterConfig, "artifactParameterName", "ticket"));
logger.trace("Loading artifact parameter name property: {}", this.artifactParameterName);
setServiceParameterName(getPropertyFromInitParams(filterConfig, "serviceParameterName", "service"));
logger.trace("Loading serviceParameterName property: {} ", this.serviceParameterName);
setEncodeServiceUrl(parseBoolean(getPropertyFromInitParams(filterConfig, "encodeServiceUrl", "true")));
logger.trace("Loading encodeServiceUrl property: {}", this.encodeServiceUrl);
setServerName(getString(ConfigurationKeys.SERVER_NAME));
setService(getString(ConfigurationKeys.SERVICE));
setEncodeServiceUrl(getBoolean(ConfigurationKeys.ENCODE_SERVICE_URL));
initInternal(filterConfig);
}
@ -92,8 +89,6 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
* afterPropertiesSet();
*/
public void init() {
CommonUtils.assertNotNull(this.artifactParameterName, "artifactParameterName cannot be null.");
CommonUtils.assertNotNull(this.serviceParameterName, "serviceParameterName cannot be null.");
CommonUtils.assertTrue(CommonUtils.isNotEmpty(this.serverName) || CommonUtils.isNotEmpty(this.service),
"serverName or service must be set.");
CommonUtils.assertTrue(CommonUtils.isBlank(this.serverName) || CommonUtils.isBlank(this.service),
@ -107,7 +102,7 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
protected final String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response) {
return CommonUtils.constructServiceUrl(request, response, this.service, this.serverName,
this.artifactParameterName, this.encodeServiceUrl);
this.protocol.getArtifactParameterName(), this.encodeServiceUrl);
}
/**
@ -129,26 +124,14 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
this.service = service;
}
public final void setArtifactParameterName(final String artifactParameterName) {
this.artifactParameterName = artifactParameterName;
}
public final void setServiceParameterName(final String serviceParameterName) {
this.serviceParameterName = serviceParameterName;
}
public final void setEncodeServiceUrl(final boolean encodeServiceUrl) {
this.encodeServiceUrl = encodeServiceUrl;
}
public final String getArtifactParameterName() {
return this.artifactParameterName;
protected Protocol getProtocol() {
return this.protocol;
}
public final String getServiceParameterName() {
return this.serviceParameterName;
}
/**
* Template method to allow you to change how you retrieve the ticket.
*
@ -156,6 +139,6 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
* @return the ticket if its found, null otherwise.
*/
protected String retrieveTicketFromRequest(final HttpServletRequest request) {
return CommonUtils.safeGetParameter(request, getArtifactParameterName());
return CommonUtils.safeGetParameter(request, this.protocol.getArtifactParameterName());
}
}

View File

@ -18,10 +18,13 @@
*/
package org.jasig.cas.client.util;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.jasig.cas.client.configuration.ConfigurationKey;
import org.jasig.cas.client.configuration.ConfigurationStrategy;
import org.jasig.cas.client.configuration.ConfigurationStrategyName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,94 +37,41 @@ import org.slf4j.LoggerFactory;
*/
public abstract class AbstractConfigurationFilter implements Filter {
private static final String CONFIGURATION_STRATEGY_KEY = "configurationStrategy";
protected final Logger logger = LoggerFactory.getLogger(getClass());
private boolean ignoreInitConfiguration = false;
/**
* Retrieves the property from the FilterConfig. First it checks the FilterConfig's initParameters to see if it
* has a value.
* If it does, it returns that, otherwise it retrieves the ServletContext's initParameters and returns that value if any.
* <p>
* Finally, it will check JNDI if all other methods fail. All the JNDI properties should be stored under either java:comp/env/cas/SHORTFILTERNAME/{propertyName}
* or java:comp/env/cas/{propertyName}
* <p>
* Essentially the documented order is:
* <ol>
* <li>FilterConfig.getInitParameter</li>
* <li>ServletContext.getInitParameter</li>
* <li>java:comp/env/cas/SHORTFILTERNAME/{propertyName}</li>
* <li>java:comp/env/cas/{propertyName}</li>
* <li>Default Value</li>
* </ol>
*
*
* @param filterConfig the Filter Configuration.
* @param propertyName the property to retrieve.
* @param defaultValue the default value if the property is not found.
* @return the property value, following the above conventions. It will always return the more specific value (i.e.
* filter vs. context).
*/
protected final String getPropertyFromInitParams(final FilterConfig filterConfig, final String propertyName,
final String defaultValue) {
final String value = filterConfig.getInitParameter(propertyName);
private ConfigurationStrategy configurationStrategy;
if (CommonUtils.isNotBlank(value)) {
if ("renew".equals(propertyName)) {
throw new IllegalArgumentException(
"Renew MUST be specified via context parameter or JNDI environment to avoid misconfiguration.");
}
logger.info("Property [{}] loaded from FilterConfig.getInitParameter with value [{}]", propertyName, value);
return value;
}
final String value2 = filterConfig.getServletContext().getInitParameter(propertyName);
if (CommonUtils.isNotBlank(value2)) {
logger.info("Property [{}] loaded from ServletContext.getInitParameter with value [{}]", propertyName,
value2);
return value2;
}
InitialContext context;
try {
context = new InitialContext();
} catch (final NamingException e) {
logger.warn(e.getMessage(), e);
return defaultValue;
}
final String shortName = this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".") + 1);
final String value3 = loadFromContext(context, "java:comp/env/cas/" + shortName + "/" + propertyName);
if (CommonUtils.isNotBlank(value3)) {
logger.info("Property [{}] loaded from JNDI Filter Specific Property with value [{}]", propertyName, value3);
return value3;
}
final String value4 = loadFromContext(context, "java:comp/env/cas/" + propertyName);
if (CommonUtils.isNotBlank(value4)) {
logger.info("Property [{}] loaded from JNDI with value [{}]", propertyName, value4);
return value4;
}
logger.info("Property [{}] not found. Using default value [{}]", propertyName, defaultValue);
return defaultValue;
public void init(FilterConfig filterConfig) throws ServletException {
final String configurationStrategyName = filterConfig.getServletContext().getInitParameter(CONFIGURATION_STRATEGY_KEY);
this.configurationStrategy = ReflectUtils.newInstance(ConfigurationStrategyName.resolveToConfigurationStrategy(configurationStrategyName));
this.configurationStrategy.init(filterConfig, getClass());
}
protected final boolean parseBoolean(final String value) {
return ((value != null) && value.equalsIgnoreCase("true"));
protected final boolean getBoolean(final ConfigurationKey<Boolean> configurationKey) {
return this.configurationStrategy.getBoolean(configurationKey);
}
protected final String loadFromContext(final InitialContext context, final String path) {
try {
return (String) context.lookup(path);
} catch (final NamingException e) {
return null;
}
protected final String getString(final ConfigurationKey<String> configurationKey) {
return this.configurationStrategy.getString(configurationKey);
}
public final void setIgnoreInitConfiguration(boolean ignoreInitConfiguration) {
protected final long getLong(final ConfigurationKey<Long> configurationKey) {
return this.configurationStrategy.getLong(configurationKey);
}
protected final int getInt(final ConfigurationKey<Integer> configurationKey) {
return this.configurationStrategy.getInt(configurationKey);
}
protected final <T> Class<? extends T> getClass(final ConfigurationKey<Class<? extends T>> configurationKey) {
return this.configurationStrategy.getClass(configurationKey);
}
public final void setIgnoreInitConfiguration(final boolean ignoreInitConfiguration) {
this.ignoreInitConfiguration = ignoreInitConfiguration;
}

View File

@ -99,7 +99,7 @@ public final class CommonUtils {
* Assert that the statement is true, otherwise throw an exception with the
* provided message.
*
* @param cond the codition to assert is true.
* @param cond the condition to assert is true.
* @param message the message to display if the condition is not true.
*/
public static void assertTrue(final boolean cond, final String message) {
@ -108,6 +108,20 @@ public final class CommonUtils {
}
}
/**
* Assert that the statement is true, otherwise throw an exception with the
* provided message.
*
* @param cond the condition to assert is false.
* @param message the message to display if the condition is not false.
*/
public static void assertFalse(final boolean cond, final String message) {
if (cond) {
throw new IllegalArgumentException(message);
}
}
/**
* Determines whether the String is null or of length 0.
*

View File

@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.validation.Assertion;
/**
@ -82,8 +83,9 @@ public final class HttpServletRequestWrapperFilter extends AbstractConfiguration
}
public void init(final FilterConfig filterConfig) throws ServletException {
this.roleAttribute = getPropertyFromInitParams(filterConfig, "roleAttribute", null);
this.ignoreCase = Boolean.parseBoolean(getPropertyFromInitParams(filterConfig, "ignoreCase", "false"));
super.init(filterConfig);
this.roleAttribute = getString(ConfigurationKeys.ROLE_ATTRIBUTE);
this.ignoreCase = getBoolean(ConfigurationKeys.IGNORE_CASE);
}
final class CasHttpServletRequestWrapper extends HttpServletRequestWrapper {

View File

@ -25,6 +25,9 @@ import javax.net.ssl.HostnameVerifier;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
@ -68,6 +71,10 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
*/
private boolean useSession = true;
protected AbstractTicketValidationFilter(final Protocol protocol) {
super(protocol);
}
/**
* Template method to return the appropriate validator.
*
@ -81,12 +88,11 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
/**
* Gets the ssl config to use for HTTPS connections
* if one is configured for this filter.
* @param filterConfig Servlet filter configuration.
* @return Properties that can contains key/trust info for Client Side Certificates
*/
protected Properties getSSLConfig(final FilterConfig filterConfig) {
protected Properties getSSLConfig() {
final Properties properties = new Properties();
final String fileName = getPropertyFromInitParams(filterConfig, "sslConfigFile", null);
final String fileName = getString(ConfigurationKeys.SSL_CONFIG_FILE);
if (fileName != null) {
FileInputStream fis = null;
@ -106,14 +112,11 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
/**
* Gets the configured {@link HostnameVerifier} to use for HTTPS connections
* if one is configured for this filter.
* @param filterConfig Servlet filter configuration.
* @return Instance of specified host name verifier or null if none specified.
*/
protected HostnameVerifier getHostnameVerifier(final FilterConfig filterConfig) {
final String className = getPropertyFromInitParams(filterConfig, "hostnameVerifier", null);
logger.trace("Using hostnameVerifier parameter: {}", className);
final String config = getPropertyFromInitParams(filterConfig, "hostnameVerifierConfig", null);
logger.trace("Using hostnameVerifierConfig parameter: {}", config);
protected HostnameVerifier getHostnameVerifier() {
final Class<? extends HostnameVerifier> className = getClass(ConfigurationKeys.HOSTNAME_VERIFIER);
final String config = getString(ConfigurationKeys.HOSTNAME_VERIFIER_CONFIG);
if (className != null) {
if (config != null) {
return ReflectUtils.newInstance(className, config);
@ -125,14 +128,9 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
}
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
setExceptionOnValidationFailure(parseBoolean(getPropertyFromInitParams(filterConfig,
"exceptionOnValidationFailure", "false")));
logger.trace("Setting exceptionOnValidationFailure parameter: {}", this.exceptionOnValidationFailure);
setRedirectAfterValidation(parseBoolean(getPropertyFromInitParams(filterConfig, "redirectAfterValidation",
"true")));
logger.trace("Setting redirectAfterValidation parameter: {}", this.redirectAfterValidation);
setUseSession(parseBoolean(getPropertyFromInitParams(filterConfig, "useSession", "true")));
logger.trace("Setting useSession parameter: {}", this.useSession);
setExceptionOnValidationFailure(getBoolean(ConfigurationKeys.EXCEPTION_ON_VALIDATION_FAILURE));
setRedirectAfterValidation(getBoolean(ConfigurationKeys.REDIRECT_AFTER_VALIDATION));
setUseSession(getBoolean(ConfigurationKeys.USE_SESSION));
if (!this.useSession && this.redirectAfterValidation) {
logger.warn("redirectAfterValidation parameter may not be true when useSession parameter is false. Resetting it to false in order to prevent infinite redirects.");

View File

@ -19,29 +19,36 @@
package org.jasig.cas.client.validation;
import javax.servlet.FilterConfig;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
/**
* Implementation of AbstractTicketValidatorFilter that instanciates a Cas10TicketValidator.
* Implementation of AbstractTicketValidatorFilter that creates a Cas10TicketValidator.
* <p>Deployers can provide the "casServerPrefix" and the "renew" attributes via the standard context or filter init
* parameters.
*
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1
*/
public class Cas10TicketValidationFilter extends AbstractTicketValidationFilter {
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final String casServerUrlPrefix = getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", null);
final Cas10TicketValidator validator = new Cas10TicketValidator(casServerUrlPrefix);
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
public Cas10TicketValidationFilter() {
super(Protocol.CAS1);
}
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig),
getSSLConfig(filterConfig));
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final String casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX);
final Cas10TicketValidator validator = new Cas10TicketValidator(casServerUrlPrefix);
validator.setRenew(getBoolean(ConfigurationKeys.RENEW));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(),
getSSLConfig());
validator.setURLConnectionFactory(factory);
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));
validator.setEncoding(getString(ConfigurationKeys.ENCODING));
return validator;
}

View File

@ -23,16 +23,21 @@ import java.util.*;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.proxy.*;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
import static org.jasig.cas.client.configuration.ConfigurationKeys.*;
/**
* Creates either a CAS20ProxyTicketValidator or a CAS20ServiceTicketValidator depending on whether any of the
* proxy parameters are set.
* <p>
* <p/>
* 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}.
*
@ -40,20 +45,20 @@ import org.jasig.cas.client.util.ReflectUtils;
* @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[] { "proxyGrantingTicketStorageClass",
"proxyReceptorUrl", "acceptAnyProxy", "allowedProxyChains", "casServerUrlPrefix", "proxyCallbackUrl",
"renew", "exceptionOnValidationFailure", "redirectAfterValidation", "useSession", "serverName", "service",
"artifactParameterName", "serviceParameterName", "encodeServiceUrl", "millisBetweenCleanUps",
"hostnameVerifier", "encoding", "config", "ticketValidatorClass" };
private static final int DEFAULT_MILLIS_BETWEEN_CLEANUPS = 60 * 1000;
private static final String[] RESERVED_INIT_PARAMS = new String[]{ARTIFACT_PARAMETER_NAME.getName(), SERVER_NAME.getName(), SERVICE.getName(), RENEW.getName(), LOGOUT_PARAMETER_NAME.getName(),
ARTIFACT_PARAMETER_OVER_POST.getName(), EAGERLY_CREATE_SESSIONS.getName(), ENCODE_SERVICE_URL.getName(), SSL_CONFIG_FILE.getName(), ROLE_ATTRIBUTE.getName(), IGNORE_CASE.getName(),
CAS_SERVER_LOGIN_URL.getName(), GATEWAY.getName(), AUTHENTICATION_REDIRECT_STRATEGY_CLASS.getName(), GATEWAY_STORAGE_CLASS.getName(), CAS_SERVER_URL_PREFIX.getName(), ENCODING.getName(),
TOLERANCE.getName(), DISABLE_XML_SCHEMA_VALIDATION.getName(), IGNORE_PATTERN.getName(), IGNORE_URL_PATTERN_TYPE.getName(), HOSTNAME_VERIFIER.getName(), HOSTNAME_VERIFIER_CONFIG.getName(),
EXCEPTION_ON_VALIDATION_FAILURE.getName(), REDIRECT_AFTER_VALIDATION.getName(), USE_SESSION.getName(), SECRET_KEY.getName(), CIPHER_ALGORITHM.getName(), PROXY_RECEPTOR_URL.getName(),
PROXY_GRANTING_TICKET_STORAGE_CLASS.getName(), MILLIS_BETWEEN_CLEAN_UPS.getName(), ACCEPT_ANY_PROXY.getName(), ALLOWED_PROXY_CHAINS.getName(), TICKET_VALIDATOR_CLASS.getName(),
PROXY_CALLBACK_URL.getName(), FRONT_LOGOUT_PARAMETER_NAME.getName(), RELAY_STATE_PARAMETER_NAME.getName()
};
/**
* The URL to send to the CAS server as the URL that will process proxying requests on the CAS client.
* The URL to send to the CAS server as the URL that will process proxying requests on the CAS client.
*/
private String proxyReceptorUrl;
@ -68,20 +73,22 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
*/
private ProxyGrantingTicketStorage proxyGrantingTicketStorage = new ProxyGrantingTicketStorageImpl();
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
setProxyReceptorUrl(getPropertyFromInitParams(filterConfig, "proxyReceptorUrl", null));
public Cas20ProxyReceivingTicketValidationFilter() {
super(Protocol.CAS2);
}
final String proxyGrantingTicketStorageClass = getPropertyFromInitParams(filterConfig,
"proxyGrantingTicketStorageClass", null);
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
setProxyReceptorUrl(getString(ConfigurationKeys.PROXY_RECEPTOR_URL));
final Class<? extends ProxyGrantingTicketStorage> proxyGrantingTicketStorageClass = getClass(ConfigurationKeys.PROXY_GRANTING_TICKET_STORAGE_CLASS);
if (proxyGrantingTicketStorageClass != null) {
this.proxyGrantingTicketStorage = ReflectUtils.newInstance(proxyGrantingTicketStorageClass);
if (this.proxyGrantingTicketStorage instanceof AbstractEncryptedProxyGrantingTicketStorageImpl) {
final AbstractEncryptedProxyGrantingTicketStorageImpl p = (AbstractEncryptedProxyGrantingTicketStorageImpl) this.proxyGrantingTicketStorage;
final String cipherAlgorithm = getPropertyFromInitParams(filterConfig, "cipherAlgorithm",
AbstractEncryptedProxyGrantingTicketStorageImpl.DEFAULT_ENCRYPTION_ALGORITHM);
final String secretKey = getPropertyFromInitParams(filterConfig, "secretKey", null);
final String cipherAlgorithm = getString(ConfigurationKeys.CIPHER_ALGORITHM);
final String secretKey = getString(ConfigurationKeys.SECRET_KEY);
p.setCipherAlgorithm(cipherAlgorithm);
@ -95,9 +102,7 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
}
}
logger.trace("Setting proxyReceptorUrl parameter: {}", this.proxyReceptorUrl);
this.millisBetweenCleanUps = Integer.parseInt(getPropertyFromInitParams(filterConfig, "millisBetweenCleanUps",
Integer.toString(DEFAULT_MILLIS_BETWEEN_CLEANUPS)));
this.millisBetweenCleanUps = getInt(ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS);
super.initInternal(filterConfig);
}
@ -115,13 +120,13 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
this.timer.schedule(this.timerTask, this.millisBetweenCleanUps, this.millisBetweenCleanUps);
}
private <T> T createNewTicketValidator(final String ticketValidatorClass, final String casServerUrlPrefix,
final Class<T> clazz) {
if (CommonUtils.isBlank(ticketValidatorClass)) {
private <T> T createNewTicketValidator(final Class<? extends Cas20ServiceTicketValidator> ticketValidatorClass, final String casServerUrlPrefix,
final Class<T> clazz) {
if (ticketValidatorClass == null) {
return ReflectUtils.newInstance(clazz, casServerUrlPrefix);
}
return ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix);
return (T) ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix);
}
/**
@ -131,38 +136,37 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
* @return a fully constructed TicketValidator.
*/
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final String allowAnyProxy = getPropertyFromInitParams(filterConfig, "acceptAnyProxy", null);
final String allowedProxyChains = getPropertyFromInitParams(filterConfig, "allowedProxyChains", null);
final String casServerUrlPrefix = getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", null);
final String ticketValidatorClass = getPropertyFromInitParams(filterConfig, "ticketValidatorClass", null);
final boolean allowAnyProxy = getBoolean(ConfigurationKeys.ACCEPT_ANY_PROXY);
final String allowedProxyChains = getString(ConfigurationKeys.ALLOWED_PROXY_CHAINS);
final String casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX);
final Class<? extends Cas20ServiceTicketValidator> ticketValidatorClass = getClass(ConfigurationKeys.TICKET_VALIDATOR_CLASS);
final Cas20ServiceTicketValidator validator;
if (CommonUtils.isNotBlank(allowAnyProxy) || CommonUtils.isNotBlank(allowedProxyChains)) {
if (allowAnyProxy || CommonUtils.isNotBlank(allowedProxyChains)) {
final Cas20ProxyTicketValidator v = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix,
Cas20ProxyTicketValidator.class);
v.setAcceptAnyProxy(parseBoolean(allowAnyProxy));
v.setAcceptAnyProxy(allowAnyProxy);
v.setAllowedProxyChains(CommonUtils.createProxyList(allowedProxyChains));
validator = v;
} else {
validator = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix,
Cas20ServiceTicketValidator.class);
}
validator.setProxyCallbackUrl(getPropertyFromInitParams(filterConfig, "proxyCallbackUrl", null));
validator.setProxyCallbackUrl(getString(ConfigurationKeys.PROXY_CALLBACK_URL));
validator.setProxyGrantingTicketStorage(this.proxyGrantingTicketStorage);
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig),
getSSLConfig(filterConfig));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(),
getSSLConfig());
validator.setURLConnectionFactory(factory);
validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getPropertyFromInitParams(filterConfig,
"encoding", null), factory));
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));
validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getString(ConfigurationKeys.ENCODING), factory));
validator.setRenew(getBoolean(ConfigurationKeys.RENEW));
validator.setEncoding(getString(ConfigurationKeys.ENCODING));
final Map<String, String> additionalParameters = new HashMap<String, String>();
final List<String> params = Arrays.asList(RESERVED_INIT_PARAMS);
for (final Enumeration<?> e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
for (final Enumeration<?> e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) {
final String s = (String) e.nextElement();
if (!params.contains(s)) {
@ -183,7 +187,7 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
* This processes the ProxyReceptor request before the ticket validation code executes.
*/
protected final boolean preFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final String requestUri = request.getRequestURI();

View File

@ -19,13 +19,15 @@
package org.jasig.cas.client.validation;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
/**
* Implementation of TicketValidationFilter that can instanciate a SAML 1.1 Ticket Validator.
* <p>
* <p/>
* Deployers can provide the "casServerUrlPrefix" and "tolerance" properties of the Saml11TicketValidator via the
* context or filter init parameters.
*
@ -36,34 +38,21 @@ import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
public class Saml11TicketValidationFilter extends AbstractTicketValidationFilter {
public Saml11TicketValidationFilter() {
setArtifactParameterName("SAMLart");
setServiceParameterName("TARGET");
}
protected final void initInternal(final FilterConfig filterConfig) throws ServletException {
super.initInternal(filterConfig);
logger.warn("SAML1.1 compliance requires the [artifactParameterName] and [serviceParameterName] to be set to specified values.");
logger.warn("This filter will overwrite any user-provided values (if any are provided)");
setArtifactParameterName("SAMLart");
setServiceParameterName("TARGET");
super(Protocol.SAML11);
}
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final Saml11TicketValidator validator = new Saml11TicketValidator(getPropertyFromInitParams(filterConfig,
"casServerUrlPrefix", null));
final String tolerance = getPropertyFromInitParams(filterConfig, "tolerance", "1000");
validator.setTolerance(Long.parseLong(tolerance));
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
final Saml11TicketValidator validator = new Saml11TicketValidator(getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX));
final long tolerance = getLong(ConfigurationKeys.TOLERANCE);
validator.setTolerance(tolerance);
validator.setRenew(getBoolean(ConfigurationKeys.RENEW));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig),
getSSLConfig(filterConfig));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(),
getSSLConfig());
validator.setURLConnectionFactory(factory);
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));
validator.setDisableXmlSchemaValidation(parseBoolean(getPropertyFromInitParams(filterConfig,
"disableXmlSchemaValidation", "false")));
validator.setEncoding(getString(ConfigurationKeys.ENCODING));
validator.setDisableXmlSchemaValidation(getBoolean(ConfigurationKeys.DISABLE_XML_SCHEMA_VALIDATION));
return validator;
}
}

View File

@ -0,0 +1,27 @@
package org.jasig.cas.client.configuration;
import org.junit.Test;
import static org.junit.Assert.*;
public final class ConfigurationKeyTests {
@Test
public void gettersWithNoDefaultValue() {
final String name = "name";
final ConfigurationKey<Boolean> configurationKey = new ConfigurationKey<Boolean>(name);
assertEquals(name, configurationKey.getName());
assertNull(configurationKey.getDefaultValue());
}
@Test
public void gettersWithDefaultValue() {
final String name = "name";
final Boolean defaultValue = Boolean.TRUE;
final ConfigurationKey<Boolean> configurationKey = new ConfigurationKey<Boolean>(name, defaultValue);
assertEquals(name, configurationKey.getName());
assertEquals(defaultValue, configurationKey.getDefaultValue());
}
}

View File

@ -0,0 +1,16 @@
package org.jasig.cas.client.configuration;
import org.junit.Test;
import static org.junit.Assert.*;
public final class ConfigurationStrategyNameTests {
@Test
public void stringToClass() {
assertEquals(JndiConfigurationStrategyImpl.class, ConfigurationStrategyName.resolveToConfigurationStrategy(ConfigurationStrategyName.JNDI.name()));
assertEquals(WebXmlConfigurationStrategyImpl.class, ConfigurationStrategyName.resolveToConfigurationStrategy(ConfigurationStrategyName.WEB_XML.name()));
assertEquals(LegacyConfigurationStrategyImpl.class, ConfigurationStrategyName.resolveToConfigurationStrategy(ConfigurationStrategyName.DEFAULT.name()));
assertEquals(LegacyConfigurationStrategyImpl.class, ConfigurationStrategyName.resolveToConfigurationStrategy("bleh!"));
}
}

View File

@ -0,0 +1,127 @@
package org.jasig.cas.client.configuration;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockServletContext;
import static org.junit.Assert.*;
public final class WebXmlConfigurationStrategyImplTests {
private WebXmlConfigurationStrategyImpl impl;
private MockFilterConfig filterConfig;
@Before
public void setUp() throws Exception {
this.filterConfig = new MockFilterConfig();
this.impl = new WebXmlConfigurationStrategyImpl();
this.impl.init(this.filterConfig, AbstractCasFilter.class);
}
@Test
public void noKeyFoundGetDefaultForBoolean() {
final ConfigurationKey<Boolean> key = ConfigurationKeys.ACCEPT_ANY_PROXY;
assertEquals(key.getDefaultValue(), this.impl.getBoolean(key));
}
@Test
public void noKeyFoundGetDefaultForString() {
final ConfigurationKey<String> key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME;
assertEquals(key.getDefaultValue(), this.impl.getString(key));
}
@Test
public void noKeyFoundGetDefaultForLong() {
final ConfigurationKey<Long> key = ConfigurationKeys.TOLERANCE;
assertEquals(key.getDefaultValue().longValue(), this.impl.getLong(key));
}
@Test
public void noKeyFoundGetDefaultForInt() {
final ConfigurationKey<Integer> key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS;
assertEquals(key.getDefaultValue().intValue(), this.impl.getInt(key));
}
@Test
public void filterConfigValueForBoolean() {
final ConfigurationKey<Boolean> key = ConfigurationKeys.ACCEPT_ANY_PROXY;
final Boolean value = Boolean.TRUE;
this.filterConfig.addInitParameter(key.getName(), value.toString());
assertEquals(value, this.impl.getBoolean(key));
}
@Test
public void filterConfigValueForString() {
final ConfigurationKey<String> key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME;
final String value = "foobar";
this.filterConfig.addInitParameter(key.getName(), value);
assertEquals(value, this.impl.getString(key));
}
@Test
public void filterConfigValueForLong() {
final ConfigurationKey<Long> key = ConfigurationKeys.TOLERANCE;
final long value = 1500;
this.filterConfig.addInitParameter(key.getName(), Long.toString(value));
assertEquals(value, this.impl.getLong(key));
}
@Test
public void filterConfigValueForInt() {
final ConfigurationKey<Integer> key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS;
final int value = 1500;
this.filterConfig.addInitParameter(key.getName(), Integer.toString(value));
assertEquals(value, this.impl.getInt(key));
}
@Test
public void servletConfigValueForBoolean() {
final ConfigurationKey<Boolean> key = ConfigurationKeys.ACCEPT_ANY_PROXY;
final Boolean value = Boolean.TRUE;
final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext();
context.addInitParameter(key.getName(), value.toString());
assertEquals(value, this.impl.getBoolean(key));
}
@Test
public void servletConfigValueForString() {
final ConfigurationKey<String> key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME;
final String value = "foobar";
final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext();
context.addInitParameter(key.getName(), value);
assertEquals(value, this.impl.getString(key));
}
@Test
public void servletConfigValueForLong() {
final ConfigurationKey<Long> key = ConfigurationKeys.TOLERANCE;
final long value = 1500;
final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext();
context.addInitParameter(key.getName(), Long.toString(value));
assertEquals(value, this.impl.getLong(key));
}
@Test
public void servletConfigValueForInt() {
final ConfigurationKey<Integer> key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS;
final int value = 1500;
final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext();
context.addInitParameter(key.getName(), Integer.toString(value));
assertEquals(value, this.impl.getInt(key));
}
}

View File

@ -25,6 +25,8 @@ import java.io.IOException;
import javax.servlet.ServletException;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
@ -35,12 +37,12 @@ import org.springframework.mock.web.MockHttpSession;
/**
* Tests {@link SingleSignOutFilter}.
*
*
* @author Jerome Leleu
* @since 3.3.1
*/
public class SingleSignOutFilterTests {
private final static String CAS_SERVER_URL_PREFIX = "http://myhost.com/mycasserver";
private final static String TICKET = "ST-yyyyy";
private final static String RELAY_STATE = "e1s1";
@ -49,7 +51,7 @@ public class SingleSignOutFilterTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private MockFilterChain filterChain;
@Before
public void setUp() throws Exception {
filter = new SingleSignOutFilter();
@ -60,11 +62,11 @@ public class SingleSignOutFilterTests {
response = new MockHttpServletResponse();
filterChain = new MockFilterChain();
}
@Test
public void tokenRequest() throws IOException, ServletException {
request.setParameter(SingleSignOutHandler.DEFAULT_ARTIFACT_PARAMETER_NAME, TICKET);
request.setQueryString(SingleSignOutHandler.DEFAULT_ARTIFACT_PARAMETER_NAME + "=" + TICKET);
request.setParameter(Protocol.CAS2.getArtifactParameterName(), TICKET);
request.setQueryString(Protocol.CAS2.getArtifactParameterName() + "=" + TICKET);
final MockHttpSession session = new MockHttpSession();
request.setSession(session);
filter.doFilter(request, response, filterChain);
@ -73,7 +75,7 @@ public class SingleSignOutFilterTests {
@Test
public void backChannelRequest() throws IOException, ServletException {
request.setParameter(SingleSignOutHandler.DEFAULT_LOGOUT_PARAMETER_NAME,
request.setParameter(ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue(),
LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET));
request.setMethod("POST");
final MockHttpSession session = new MockHttpSession();
@ -85,8 +87,8 @@ public class SingleSignOutFilterTests {
@Test
public void frontChannelRequest() throws IOException, ServletException {
final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET);
request.setParameter(SingleSignOutHandler.DEFAULT_FRONT_LOGOUT_PARAMETER_NAME, logoutMessage);
request.setQueryString(SingleSignOutHandler.DEFAULT_FRONT_LOGOUT_PARAMETER_NAME + "=" + logoutMessage);
request.setParameter(ConfigurationKeys.FRONT_LOGOUT_PARAMETER_NAME.getDefaultValue(), logoutMessage);
request.setQueryString(ConfigurationKeys.FRONT_LOGOUT_PARAMETER_NAME.getDefaultValue() + "=" + logoutMessage);
request.setMethod("GET");
final MockHttpSession session = new MockHttpSession();
SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().addSessionById(TICKET, session);
@ -98,16 +100,16 @@ public class SingleSignOutFilterTests {
@Test
public void frontChannelRequestRelayState() throws IOException, ServletException {
final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET);
request.setParameter(SingleSignOutHandler.DEFAULT_FRONT_LOGOUT_PARAMETER_NAME, logoutMessage);
request.setParameter(SingleSignOutHandler.DEFAULT_RELAY_STATE_PARAMETER_NAME, RELAY_STATE);
request.setQueryString(SingleSignOutHandler.DEFAULT_FRONT_LOGOUT_PARAMETER_NAME + "=" + logoutMessage + "&" +
SingleSignOutHandler.DEFAULT_RELAY_STATE_PARAMETER_NAME + "=" + RELAY_STATE);
request.setParameter(ConfigurationKeys.FRONT_LOGOUT_PARAMETER_NAME.getDefaultValue(), logoutMessage);
request.setParameter(ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue(), RELAY_STATE);
request.setQueryString(ConfigurationKeys.FRONT_LOGOUT_PARAMETER_NAME.getDefaultValue() + "=" + logoutMessage + "&" +
ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue() + "=" + RELAY_STATE);
request.setMethod("GET");
final MockHttpSession session = new MockHttpSession();
SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().addSessionById(TICKET, session);
filter.doFilter(request, response, filterChain);
assertNull(SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().removeSessionByMappingId(TICKET));
assertEquals(CAS_SERVER_URL_PREFIX + "/logout?_eventId=next&" +
SingleSignOutHandler.DEFAULT_RELAY_STATE_PARAMETER_NAME + "=" + RELAY_STATE, response.getRedirectedUrl());
ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue() + "=" + RELAY_STATE, response.getRedirectedUrl());
}
}

View File

@ -24,6 +24,8 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.jasig.cas.client.Protocol;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@ -55,6 +57,10 @@ public final class CasFilterTests {
}
private static class TestCasFilter extends AbstractCasFilter {
public TestCasFilter() {
super(Protocol.CAS2);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
// nothing to do

View File

@ -50,7 +50,10 @@ public class Cas10TicketValidationFilterTests {
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerUrlPrefix", "https://cas.example.com");
context.addInitParameter("renew", "true");
final TicketValidator validator = f.getTicketValidator(new MockFilterConfig(context));
context.addInitParameter("service", "http://www.jasig.org");
final MockFilterConfig config = new MockFilterConfig(context);
f.init(config);
final TicketValidator validator = f.getTicketValidator(config);
assertTrue(validator instanceof Cas10TicketValidator);
assertTrue(((Cas10TicketValidator) validator).isRenew());
}

View File

@ -25,6 +25,7 @@ import org.jasig.cas.client.proxy.CleanUpTimerTask;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
import org.jasig.cas.client.util.MethodFlag;
import org.junit.Test;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockServletContext;
@ -148,32 +149,40 @@ public class Cas20ProxyReceivingTicketValidationFilterTests extends TestCase {
public void testGetTicketValidator() throws Exception {
Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
filter.setProxyGrantingTicketStorage(storage);
filter.setMillisBetweenCleanUps(250);
filter.setTimer(defaultTimer);
filter.setTimerTask(new TimerTask() {
public void run() {
}
});
filter.init();
// Test case #1
final MockFilterConfig config1 = new MockFilterConfig();
config1.addInitParameter("allowedProxyChains", "https://a.example.com");
config1.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/");
config1.addInitParameter("service", "http://www.jasig.org");
filter.init(config1);
assertNotNull(filter.getTicketValidator(config1));
}
@Test
public void getTicketValidatorWithProxyChains() throws Exception {
Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
// Test case #2
final MockFilterConfig config2 = new MockFilterConfig();
config2.addInitParameter("allowedProxyChains", "https://a.example.com https://b.example.com");
config2.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/");
config2.addInitParameter("service", "http://www.jasig.org");
filter.init(config2);
assertNotNull(filter.getTicketValidator(config2));
}
@Test
public void getTIcketValidatorWithProxyChainsAndLineBreak() throws Exception {
Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
// Test case #3
final MockFilterConfig config3 = new MockFilterConfig();
config3.addInitParameter("allowedProxyChains",
"https://a.example.com https://b.example.com\nhttps://c.example.com");
config3.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/");
config3.addInitParameter("service", "http://www.jasig.org");
filter.init(config3);
assertNotNull(filter.getTicketValidator(config3));
}
@ -195,7 +204,10 @@ public class Cas20ProxyReceivingTicketValidationFilterTests extends TestCase {
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerUrlPrefix", "https://cas.example.com");
context.addInitParameter("renew", "true");
final TicketValidator validator = f.getTicketValidator(new MockFilterConfig(context));
context.addInitParameter("service", "http://www.jasig.org");
final MockFilterConfig config = new MockFilterConfig(context);
f.init(config);
final TicketValidator validator = f.getTicketValidator(config);
assertTrue(validator instanceof AbstractUrlBasedTicketValidator);
assertTrue(((AbstractUrlBasedTicketValidator) validator).isRenew());
}

View File

@ -20,6 +20,7 @@ package org.jasig.cas.client.validation;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockServletContext;
@ -50,7 +51,10 @@ public class Saml11TicketValidationFilterTests {
final MockServletContext context = new MockServletContext();
context.addInitParameter("casServerUrlPrefix", "https://cas.example.com");
context.addInitParameter("renew", "true");
final TicketValidator validator = f.getTicketValidator(new MockFilterConfig(context));
context.addInitParameter("service", "http://www.jasig.org");
final MockFilterConfig config = new MockFilterConfig(context);
f.init(config);
final TicketValidator validator = f.getTicketValidator(config);
assertTrue(validator instanceof Saml11TicketValidator);
assertTrue(((Saml11TicketValidator) validator).isRenew());
}

View File

@ -0,0 +1,16 @@
package org.jasig.cas.client.configuration;
/**
* Simple extension to the {@link org.jasig.cas.client.configuration.JndiConfigurationStrategyImpl} to provide a JBoss 7 compatible prefix.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class JBossCompatibleJndiConfigurationStrategyImpl extends JndiConfigurationStrategyImpl {
private static final String ENVIRONMENT_PREFIX = "java:/comp/env/cas/";
public JBossCompatibleJndiConfigurationStrategyImpl() {
super(ENVIRONMENT_PREFIX);
}
}

View File

@ -27,6 +27,8 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.jaas.AssertionPrincipal;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
@ -50,12 +52,16 @@ import org.jboss.web.tomcat.security.login.WebAuthentication;
*/
public final class WebAuthenticationFilter extends AbstractCasFilter {
public WebAuthenticationFilter() {
super(Protocol.CAS2);
}
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final HttpSession session = request.getSession();
final String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());
final String ticket = CommonUtils.safeGetParameter(request, getProtocol().getArtifactParameterName());
if (session != null && session.getAttribute(CONST_CAS_ASSERTION) == null && ticket != null) {
try {