From 603beabefcacb7b852631e89f7c5b7bda6778027 Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Wed, 9 Apr 2014 22:12:26 -0400 Subject: [PATCH 1/7] CASC-200 Create a ConfigurationStrategy to allow for pluggable configurations. Problem: The lookup strategy for configuration is hard-coded into the filter, making it impossible to replace or expand. Solution: Pull the strategies into their own classees and make it configurable. Default to the previous strategy. QA Notes: The current unit tests work. New unit tests for the configuration will have to be added once the design is approved. --- cas-client-core/pom.xml | 7 + .../java/org/jasig/cas/client/Protocol.java | 28 ++++ .../authentication/AuthenticationFilter.java | 35 ++--- .../Saml11AuthenticationFilter.java | 17 +-- .../BaseConfigurationStrategy.java | 95 +++++++++++++ .../configuration/ConfigurationKey.java | 42 ++++++ .../configuration/ConfigurationKeys.java | 58 ++++++++ .../configuration/ConfigurationStrategy.java | 62 +++++++++ .../ConfigurationStrategyName.java | 51 +++++++ .../JndiConfigurationStrategyImpl.java | 75 ++++++++++ .../LegacyConfigurationStrategyImpl.java | 35 +++++ .../WebXmlConfigurationStrategyImpl.java | 42 ++++++ .../jaas/Servlet3AuthenticationFilter.java | 7 +- ...cryptedProxyGrantingTicketStorageImpl.java | 6 +- .../client/session/SingleSignOutFilter.java | 22 ++- .../client/session/SingleSignOutHandler.java | 15 +- .../cas/client/util/AbstractCasFilter.java | 49 +++---- .../util/AbstractConfigurationFilter.java | 108 ++++----------- .../jasig/cas/client/util/CommonUtils.java | 16 ++- .../util/HttpServletRequestWrapperFilter.java | 6 +- .../AbstractTicketValidationFilter.java | 32 ++--- .../Cas10TicketValidationFilter.java | 25 ++-- ...0ProxyReceivingTicketValidationFilter.java | 71 +++++----- .../Saml11TicketValidationFilter.java | 37 ++--- .../configuration/ConfigurationKeyTests.java | 27 ++++ .../ConfigurationStrategyNameTests.java | 16 +++ .../WebXmlConfigurationStrategyImplTests.java | 128 ++++++++++++++++++ .../session/SingleSignOutFilterTests.java | 30 ++-- .../jasig/cas/client/util/CasFilterTests.java | 6 + .../Cas10TicketValidationFilterTests.java | 5 +- ...yReceivingTicketValidationFilterTests.java | 30 ++-- .../Saml11TicketValidationFilterTests.java | 6 +- ...mpatibleJndiConfigurationStrategyImpl.java | 16 +++ .../WebAuthenticationFilter.java | 8 +- 34 files changed, 932 insertions(+), 281 deletions(-) create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java create mode 100644 cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java create mode 100644 cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java create mode 100644 cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java create mode 100644 cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java diff --git a/cas-client-core/pom.xml b/cas-client-core/pom.xml index f37b084..3cecc14 100644 --- a/cas-client-core/pom.xml +++ b/cas-client-core/pom.xml @@ -75,6 +75,13 @@ test + + org.mockito + mockito-all + 1.10.8 + test + + log4j log4j diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java b/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java new file mode 100644 index 0000000..184104f --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java @@ -0,0 +1,28 @@ +package org.jasig.cas.client; + +/** + * Created by battags on 10/14/14. + */ +public enum Protocol { + + + + CAS1("ticket", "service"), CAS2(CAS1.getArtifactParameterName(), CAS1.getServiceParameterName()), 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; + } + + public String getArtifactParameterName() { + return this.artifactParameterName; + } + + public String getServiceParameterName() { + return this.serviceParameterName; + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java index b77c64c..d5e7fe4 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java @@ -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 ignoreUrlMatcherClass = PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType); @@ -113,14 +117,13 @@ public class AuthenticationFilter extends AbstractCasFilter { } } - final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null); + final Class 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 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); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java index 6c853ec..63483b2 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java @@ -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. + * Extension to the default Authentication filter that sets the required SAML11.1 artifact parameter name and service parameter name. *

- * 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); } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java new file mode 100644 index 0000000..384f89d --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java @@ -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 configurationKey) { + return getValue(configurationKey, new Parser() { + public Boolean parse(final String value) { + return BooleanUtils.toBoolean(value); + } + }); + } + + public final long getLong(final ConfigurationKey configurationKey) { + return getValue(configurationKey, new Parser() { + public Long parse(final String value) { + return NumberUtils.toLong(value, configurationKey.getDefaultValue()); + } + }); + } + + public final int getInt(final ConfigurationKey configurationKey) { + return getValue(configurationKey, new Parser() { + public Integer parse(final String value) { + return NumberUtils.toInt(value, configurationKey.getDefaultValue()); + } + }); + } + + public final String getString(final ConfigurationKey configurationKey) { + return getValue(configurationKey, new Parser() { + public String parse(final String value) { + return value; + } + }); + } + + public Class getClass(final ConfigurationKey> configurationKey) { + return getValue(configurationKey, new Parser>() { + public Class parse(final String value) { + try { + return ReflectUtils.loadClass(value); + } catch (final IllegalArgumentException e) { + return configurationKey.getDefaultValue(); + } + } + }); + } + + private T getValue(final ConfigurationKey configurationKey, final Parser 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 parse(String value); + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java new file mode 100644 index 0000000..f6c0df7 --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java @@ -0,0 +1,42 @@ +package org.jasig.cas.client.configuration; + +/** + * Holder class to represent a particular configuration key and its optional default value. + * + * @author Scott Battaglia + * @since 3.4.0 + */ +public final class ConfigurationKey { + + private final String name; + + private final E defaultValue; + + public ConfigurationKey(final String name) { + this(name, null); + } + + public ConfigurationKey(final String name, final E defaultValue) { + 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 null value indicates that there is no default. + * + * @return the default value or null. + */ + public E getDefaultValue() { + return this.defaultValue; + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java new file mode 100644 index 0000000..138c459 --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java @@ -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 ARTIFACT_PARAMETER_NAME = new ConfigurationKey("artifactParameterName", Protocol.CAS2.getArtifactParameterName()); + ConfigurationKey SERVER_NAME = new ConfigurationKey("serverName", null); + ConfigurationKey SERVICE = new ConfigurationKey("service"); + ConfigurationKey RENEW = new ConfigurationKey("renew", Boolean.FALSE); + ConfigurationKey LOGOUT_PARAMETER_NAME = new ConfigurationKey("logoutParameterName", "logoutRequest"); + ConfigurationKey ARTIFACT_PARAMETER_OVER_POST = new ConfigurationKey("artifactParameterOverPost", Boolean.FALSE); + ConfigurationKey EAGERLY_CREATE_SESSIONS = new ConfigurationKey("eagerlyCreateSessions", Boolean.TRUE); + ConfigurationKey ENCODE_SERVICE_URL = new ConfigurationKey("encodeServiceUrl", Boolean.TRUE); + ConfigurationKey SSL_CONFIG_FILE = new ConfigurationKey("sslConfigFile", null); + ConfigurationKey ROLE_ATTRIBUTE = new ConfigurationKey("roleAttribute", null); + ConfigurationKey IGNORE_CASE = new ConfigurationKey("ignoreCase", Boolean.FALSE); + ConfigurationKey CAS_SERVER_LOGIN_URL = new ConfigurationKey("casServerLoginUrl", null); + ConfigurationKey GATEWAY = new ConfigurationKey("gateway", Boolean.FALSE); + ConfigurationKey> AUTHENTICATION_REDIRECT_STRATEGY_CLASS = new ConfigurationKey>("authenticationRedirectStrategyClass", null); + ConfigurationKey> GATEWAY_STORAGE_CLASS = new ConfigurationKey>("gatewayStorageClass", DefaultGatewayResolverImpl.class); + ConfigurationKey CAS_SERVER_URL_PREFIX = new ConfigurationKey("casServerUrlPrefix", null); + ConfigurationKey ENCODING = new ConfigurationKey("encoding", null); + ConfigurationKey TOLERANCE = new ConfigurationKey("tolerance", 1000L); + ConfigurationKey DISABLE_XML_SCHEMA_VALIDATION = new ConfigurationKey("disableXmlSchemaValidation", Boolean.FALSE); + ConfigurationKey IGNORE_PATTERN = new ConfigurationKey("ignorePattern", null); + ConfigurationKey IGNORE_URL_PATTERN_TYPE = new ConfigurationKey("ignoreUrlPatternType", "REGEX"); + ConfigurationKey> HOSTNAME_VERIFIER = new ConfigurationKey>("hostnameVerifier", null); + ConfigurationKey HOSTNAME_VERIFIER_CONFIG = new ConfigurationKey("hostnameVerifierConfig", null); + ConfigurationKey EXCEPTION_ON_VALIDATION_FAILURE = new ConfigurationKey("exceptionOnValidationFailure", Boolean.TRUE); + ConfigurationKey REDIRECT_AFTER_VALIDATION = new ConfigurationKey("redirectAfterValidation", Boolean.TRUE); + ConfigurationKey USE_SESSION = new ConfigurationKey("useSession", Boolean.TRUE); + ConfigurationKey SECRET_KEY = new ConfigurationKey("secretKey", null); + ConfigurationKey CIPHER_ALGORITHM = new ConfigurationKey("cipherAlgorithm", "DESede"); + ConfigurationKey PROXY_RECEPTOR_URL = new ConfigurationKey("proxyReceptorUrl", null); + ConfigurationKey> PROXY_GRANTING_TICKET_STORAGE_CLASS = new ConfigurationKey>("proxyGrantingTicketStorageClass", ProxyGrantingTicketStorageImpl.class); + ConfigurationKey MILLIS_BETWEEN_CLEAN_UPS = new ConfigurationKey("millisBetweenCleanUps", 60000); + ConfigurationKey ACCEPT_ANY_PROXY = new ConfigurationKey("acceptAnyProxy", Boolean.FALSE); + ConfigurationKey ALLOWED_PROXY_CHAINS = new ConfigurationKey("allowedProxyChains", null); + ConfigurationKey> TICKET_VALIDATOR_CLASS = new ConfigurationKey>("ticketValidatorClass", null); + ConfigurationKey PROXY_CALLBACK_URL = new ConfigurationKey("proxyCallbackUrl", null); + ConfigurationKey FRONT_LOGOUT_PARAMETER_NAME = new ConfigurationKey("frontLogoutParameterName", "SAMLRequest"); + ConfigurationKey RELAY_STATE_PARAMETER_NAME = new ConfigurationKey("relayStateParameterName", "RelayState"); +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java new file mode 100644 index 0000000..cd1b9dd --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java @@ -0,0 +1,62 @@ +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 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 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 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 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. + */ + Class getClass(ConfigurationKey> 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 filterClazz); +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java new file mode 100644 index 0000000..ea089fe --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java @@ -0,0 +1,51 @@ +package org.jasig.cas.client.configuration; + +import org.jasig.cas.client.util.CommonUtils; + +/** + * Enumeration to map simple names to the underlying classes so that deployers can reference the simple name in the + * web.xml 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 final Class configurationStrategyClass; + + private ConfigurationStrategyName(final Class 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 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) clazz; + } + } catch (final ClassNotFoundException e) { + // nothing we can do here + } + + return DEFAULT.configurationStrategyClass; + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java new file mode 100644 index 0000000..b81f1ee --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java @@ -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 defaultValue 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 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); + } + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java new file mode 100644 index 0000000..d1f47c3 --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java @@ -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 defaultValue. + * + * @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 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); + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java new file mode 100644 index 0000000..1c05b0b --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java @@ -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 defaultValue. + * + * @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 clazz) { + this.filterConfig = filterConfig; + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java index d39027e..e64b578 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java @@ -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 { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java b/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java index 69cc75d..24826cf 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java @@ -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 { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java index c9243e9..da533cf 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java @@ -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; /** @@ -41,19 +43,13 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter { public void init(final FilterConfig filterConfig) throws ServletException { 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", null)); - 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); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java index 5f8b46c..cc049f7 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java @@ -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; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java index 8cf47ef..6e0df5f 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java @@ -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()); } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java index 708b7bf..9d3e542 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java @@ -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. - *

- * 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} - *

- * Essentially the documented order is: - *

    - *
  1. FilterConfig.getInitParameter
  2. - *
  3. ServletContext.getInitParameter
  4. - *
  5. java:comp/env/cas/SHORTFILTERNAME/{propertyName}
  6. - *
  7. java:comp/env/cas/{propertyName}
  8. - *
  9. Default Value
  10. - *
- * - * - * @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 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 configurationKey) { + return this.configurationStrategy.getString(configurationKey); } - public final void setIgnoreInitConfiguration(boolean ignoreInitConfiguration) { + protected final long getLong(final ConfigurationKey configurationKey) { + return this.configurationStrategy.getLong(configurationKey); + } + + protected final int getInt(final ConfigurationKey configurationKey) { + return this.configurationStrategy.getInt(configurationKey); + } + + protected final Class getClass(final ConfigurationKey> configurationKey) { + return this.configurationStrategy.getClass(configurationKey); + } + + public final void setIgnoreInitConfiguration(final boolean ignoreInitConfiguration) { this.ignoreInitConfiguration = ignoreInitConfiguration; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java index 3d99171..ac0ca80 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java @@ -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. * diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java index 3512f48..a474a83 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java @@ -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 { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java index 1d27314..51df207 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java @@ -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 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."); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java index 6e142c9..aca0dee 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java @@ -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. *

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; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java index e256755..cfea9e7 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java @@ -23,6 +23,9 @@ 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; @@ -32,7 +35,7 @@ import org.jasig.cas.client.util.ReflectUtils; /** * Creates either a CAS20ProxyTicketValidator or a CAS20ServiceTicketValidator depending on whether any of the * proxy parameters are set. - *

+ *

* 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 +43,17 @@ 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", + 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; + "hostnameVerifier", "encoding", "config", "ticketValidatorClass"}; /** - * 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 +68,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 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 +97,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 +115,13 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal this.timer.schedule(this.timerTask, this.millisBetweenCleanUps, this.millisBetweenCleanUps); } - private T createNewTicketValidator(final String ticketValidatorClass, final String casServerUrlPrefix, - final Class clazz) { - if (CommonUtils.isBlank(ticketValidatorClass)) { + private T createNewTicketValidator(final Class ticketValidatorClass, final String casServerUrlPrefix, + final Class clazz) { + if (ticketValidatorClass == null) { return ReflectUtils.newInstance(clazz, casServerUrlPrefix); } - return ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix); + return (T) ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix); } /** @@ -131,38 +131,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 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 additionalParameters = new HashMap(); final List 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 +182,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(); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java index 14711ab..73aede0 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java @@ -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. - *

+ *

* 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; } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java new file mode 100644 index 0000000..add5b3f --- /dev/null +++ b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java @@ -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 configurationKey = new ConfigurationKey(name); + assertEquals(name, configurationKey.getName()); + assertNull(configurationKey.getDefaultValue()); + } + + + @Test + public void gettersWithDefaultValue() { + final String name = "name"; + final Boolean defaultValue = Boolean.TRUE; + final ConfigurationKey configurationKey = new ConfigurationKey(name, defaultValue); + assertEquals(name, configurationKey.getName()); + assertEquals(defaultValue, configurationKey.getDefaultValue()); + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java new file mode 100644 index 0000000..534ecbc --- /dev/null +++ b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java @@ -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!")); + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java new file mode 100644 index 0000000..9ec94dc --- /dev/null +++ b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java @@ -0,0 +1,128 @@ +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.*; +import static org.mockito.Mockito.*; + +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 key = ConfigurationKeys.ACCEPT_ANY_PROXY; + assertEquals(key.getDefaultValue(), this.impl.getBoolean(key)); + } + + + @Test + public void noKeyFoundGetDefaultForString() { + final ConfigurationKey key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; + assertEquals(key.getDefaultValue(), this.impl.getString(key)); + } + + + @Test + public void noKeyFoundGetDefaultForLong() { + final ConfigurationKey key = ConfigurationKeys.TOLERANCE; + assertEquals(key.getDefaultValue().longValue(), this.impl.getLong(key)); + } + + + @Test + public void noKeyFoundGetDefaultForInt() { + final ConfigurationKey key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; + assertEquals(key.getDefaultValue().intValue(), this.impl.getInt(key)); + } + + @Test + public void filterConfigValueForBoolean() { + final ConfigurationKey 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 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 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 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 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 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 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 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)); + } + +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java index 7c91f8f..93fd665 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java @@ -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()); } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java index 758dc9d..8960870 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java @@ -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 diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java index 8ccdb2f..f2da173 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java @@ -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()); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java index 89e900a..7c11042 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java @@ -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()); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java index 53d1875..e4db128 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java @@ -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()); } diff --git a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java b/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java new file mode 100644 index 0000000..99e2a0c --- /dev/null +++ b/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java @@ -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); + } +} diff --git a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java b/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java index cb4c45a..597d495 100644 --- a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java +++ b/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java @@ -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 { From a997b25f35b3d0d56cb604bf79a24c5c71bee6bb Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Wed, 9 Apr 2014 22:33:57 -0400 Subject: [PATCH 2/7] Added additional keys that were new from the single signout refactor. --- .../java/org/jasig/cas/client/session/SingleSignOutFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java index da533cf..5720a69 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java @@ -42,6 +42,7 @@ 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()) { setArtifactParameterName(getString(ConfigurationKeys.ARTIFACT_PARAMETER_NAME)); setLogoutParameterName(getString(ConfigurationKeys.LOGOUT_PARAMETER_NAME)); From 035a63fe8fdea347ec0aeed122f477b42b81b809 Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Thu, 20 Nov 2014 15:58:52 -0500 Subject: [PATCH 3/7] Added missing javadoc for Protocol enumeration --- .../main/java/org/jasig/cas/client/Protocol.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java b/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java index 184104f..b484d11 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java @@ -1,13 +1,14 @@ package org.jasig.cas.client; /** - * Created by battags on 10/14/14. + * 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.getArtifactParameterName(), CAS1.getServiceParameterName()), SAML11("SAMLart", "TARGET"); + CAS1("ticket", "service"), CAS2(CAS1), SAML11("SAMLart", "TARGET"); private final String artifactParameterName; @@ -18,6 +19,10 @@ public enum Protocol { this.serviceParameterName = serviceParameterName; } + private Protocol(final Protocol protocol) { + this(protocol.getArtifactParameterName(), protocol.getServiceParameterName()); + } + public String getArtifactParameterName() { return this.artifactParameterName; } From 31d73371244b7e576461678d491b71cf12883609 Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Thu, 20 Nov 2014 16:01:02 -0500 Subject: [PATCH 4/7] Removed unused mockito dependency --- cas-client-core/pom.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cas-client-core/pom.xml b/cas-client-core/pom.xml index 3cecc14..f37b084 100644 --- a/cas-client-core/pom.xml +++ b/cas-client-core/pom.xml @@ -75,13 +75,6 @@ test - - org.mockito - mockito-all - 1.10.8 - test - - log4j log4j From bca2c5e52d28f35b90dff53aa7cd4dd53fe7525e Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Thu, 20 Nov 2014 16:03:19 -0500 Subject: [PATCH 5/7] Unused reference to Mockito --- .../configuration/WebXmlConfigurationStrategyImplTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java index 9ec94dc..5037133 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java @@ -7,7 +7,6 @@ import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockServletContext; import static org.junit.Assert.*; -import static org.mockito.Mockito.*; public final class WebXmlConfigurationStrategyImplTests { From f65d227a4874239cc365c738cac2d0401ed96c77 Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Wed, 26 Nov 2014 22:58:12 -0500 Subject: [PATCH 6/7] Addressed formatting feedback as well as reserved keywords. --- .../Saml11AuthenticationFilter.java | 2 +- .../client/configuration/ConfigurationKey.java | 3 +++ .../configuration/ConfigurationStrategy.java | 1 - ...Cas20ProxyReceivingTicketValidationFilter.java | 15 ++++++++++----- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java index 63483b2..8a7ddae 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java @@ -21,7 +21,7 @@ package org.jasig.cas.client.authentication; import org.jasig.cas.client.Protocol; /** - * Extension to the default Authentication filter that sets the required SAML11.1 artifact parameter name and service parameter name. + * Extension to the default Authentication filter that sets the required SAML1.1 artifact parameter name and service parameter name. *

* Note, as of 3.3, the final keyword was removed to allow you to override the method to retrieve tickets, per CASC-154 * diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java index f6c0df7..dfe5150 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java @@ -1,5 +1,7 @@ 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. * @@ -17,6 +19,7 @@ public final class ConfigurationKey { } public ConfigurationKey(final String name, final E defaultValue) { + CommonUtils.assertNotNull(name, "name must not be null."); this.name = name; this.defaultValue = defaultValue; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java index cd1b9dd..15905ea 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java @@ -11,7 +11,6 @@ import javax.servlet.FilterConfig; */ 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. * diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java index cfea9e7..8c7a632 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java @@ -32,6 +32,8 @@ 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. @@ -46,11 +48,14 @@ import org.jasig.cas.client.util.ReflectUtils; */ 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 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. From c89eba71410e23319b008c5e0c75decc161adb0e Mon Sep 17 00:00:00 2001 From: Scott Battaglia Date: Sun, 30 Nov 2014 17:09:09 -0500 Subject: [PATCH 7/7] Updated try/catch loop to log when a class is not found. --- .../cas/client/configuration/ConfigurationStrategyName.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java index ea089fe..bc257f2 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java @@ -1,6 +1,8 @@ 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 @@ -13,6 +15,8 @@ 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 configurationStrategyClass; private ConfigurationStrategyName(final Class configurationStrategyClass) { @@ -43,7 +47,7 @@ public enum ConfigurationStrategyName { return (Class) clazz; } } catch (final ClassNotFoundException e) { - // nothing we can do here + LOGGER.error("Unable to locate strategy {} by name or class name. Using default strategy instead.", value, e); } return DEFAULT.configurationStrategyClass;