|
@@ -1,11 +1,15 @@
|
|
|
package org.springframework.security.config;
|
|
|
|
|
|
-import org.springframework.security.concurrent.ConcurrentSessionFilter;
|
|
|
-import org.springframework.security.context.HttpSessionContextIntegrationFilter;
|
|
|
-import org.springframework.security.ui.AbstractProcessingFilter;
|
|
|
-import org.springframework.security.ui.AuthenticationEntryPoint;
|
|
|
-import org.springframework.security.ui.rememberme.RememberMeServices;
|
|
|
-import org.springframework.security.util.FilterChainProxy;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import javax.servlet.Filter;
|
|
|
+
|
|
|
+import org.apache.commons.logging.Log;
|
|
|
+import org.apache.commons.logging.LogFactory;
|
|
|
import org.springframework.beans.BeansException;
|
|
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
|
|
import org.springframework.beans.factory.config.BeanDefinition;
|
|
@@ -13,23 +17,21 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
|
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|
|
import org.springframework.core.OrderComparator;
|
|
|
import org.springframework.core.Ordered;
|
|
|
+import org.springframework.security.concurrent.ConcurrentSessionFilter;
|
|
|
+import org.springframework.security.context.HttpSessionContextIntegrationFilter;
|
|
|
+import org.springframework.security.ui.AbstractProcessingFilter;
|
|
|
+import org.springframework.security.ui.AuthenticationEntryPoint;
|
|
|
+import org.springframework.security.ui.basicauth.BasicProcessingFilter;
|
|
|
+import org.springframework.security.ui.rememberme.RememberMeServices;
|
|
|
+import org.springframework.security.util.FilterChainProxy;
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
-import org.apache.commons.logging.Log;
|
|
|
-import org.apache.commons.logging.LogFactory;
|
|
|
-
|
|
|
-import javax.servlet.Filter;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.Iterator;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
/**
|
|
|
* Responsible for tying up the HTTP security configuration - building ordered filter stack and linking up
|
|
|
* with other beans.
|
|
|
*
|
|
|
* @author Luke Taylor
|
|
|
+ * @author Ben Alex
|
|
|
* @version $Id$
|
|
|
*/
|
|
|
public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor, Ordered {
|
|
@@ -42,16 +44,16 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
|
|
|
|
|
|
ConfigUtils.configureSecurityInterceptor(beanFactory, securityInterceptor);
|
|
|
|
|
|
- configureRememberMeSerices(beanFactory);
|
|
|
+ injectUserDetailsServiceIntoRememberMeServices(beanFactory);
|
|
|
|
|
|
- configureAuthenticationEntryPoint(beanFactory);
|
|
|
+ injectAuthenticationEntryPointIntoExceptionTranslationFilter(beanFactory);
|
|
|
|
|
|
- configureAuthenticationFilter(beanFactory);
|
|
|
+ injectRememberMeServicesIntoFiltersRequiringIt(beanFactory);
|
|
|
|
|
|
configureFilterChain(beanFactory);
|
|
|
}
|
|
|
|
|
|
- private void configureRememberMeSerices(ConfigurableListableBeanFactory beanFactory) {
|
|
|
+ private void injectUserDetailsServiceIntoRememberMeServices(ConfigurableListableBeanFactory beanFactory) {
|
|
|
try {
|
|
|
BeanDefinition rememberMeServices =
|
|
|
beanFactory.getBeanDefinition(BeanIds.REMEMBER_ME_SERVICES);
|
|
@@ -66,7 +68,7 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
|
|
|
* Sets the authentication manager, (and remember-me services, if required) on any instances of
|
|
|
* AbstractProcessingFilter
|
|
|
*/
|
|
|
- private void configureAuthenticationFilter(ConfigurableListableBeanFactory beanFactory) {
|
|
|
+ private void injectRememberMeServicesIntoFiltersRequiringIt(ConfigurableListableBeanFactory beanFactory) {
|
|
|
Map beans = beanFactory.getBeansOfType(RememberMeServices.class);
|
|
|
|
|
|
RememberMeServices rememberMeServices = null;
|
|
@@ -75,29 +77,43 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
|
|
|
rememberMeServices = (RememberMeServices) beans.values().toArray()[0];
|
|
|
}
|
|
|
|
|
|
- Iterator authFilters = beanFactory.getBeansOfType(AbstractProcessingFilter.class).values().iterator();
|
|
|
+ // Address AbstractProcessingFilter instances
|
|
|
+ Iterator filters = beanFactory.getBeansOfType(AbstractProcessingFilter.class).values().iterator();
|
|
|
|
|
|
- while (authFilters.hasNext()) {
|
|
|
- AbstractProcessingFilter filter = (AbstractProcessingFilter) authFilters.next();
|
|
|
+ while (filters.hasNext()) {
|
|
|
+ AbstractProcessingFilter filter = (AbstractProcessingFilter) filters.next();
|
|
|
|
|
|
if (rememberMeServices != null) {
|
|
|
logger.info("Using RememberMeServices " + rememberMeServices + " with filter " + filter);
|
|
|
filter.setRememberMeServices(rememberMeServices);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // Address BasicProcessingFilter instance, if it exists
|
|
|
+ // NB: For remember-me to be sent back, a user must submit a "_spring_security_remember_me" with their login request.
|
|
|
+ // Most of the time a user won't present such a parameter with their BASIC authentication request.
|
|
|
+ // In the future we might support setting the AbstractRememberMeServices.alwaysRemember = true, but I am reluctant to
|
|
|
+ // do so because it seems likely to lead to lower security for 99.99% of users if they set the property to true.
|
|
|
+ BasicProcessingFilter filter = (BasicProcessingFilter) getBeanOfType(BasicProcessingFilter.class, beanFactory);
|
|
|
+
|
|
|
+ if (filter != null && rememberMeServices != null) {
|
|
|
+ logger.info("Using RememberMeServices " + rememberMeServices + " with filter " + filter);
|
|
|
+ filter.setRememberMeServices(rememberMeServices);
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Selects the entry point that should be used in ExceptionTranslationFilter. Strategy is
|
|
|
*
|
|
|
* <ol>
|
|
|
- * <li>If only one use that.</li>
|
|
|
- * <li>If more than one, check the default interactive login Ids in order of preference</li>
|
|
|
- * <li>throw an exception (for now). TODO: Examine additional beans and types and make decision</li>
|
|
|
+ * <li>If only one, use that one.</li>
|
|
|
+ * <li>If more than one, use the form login entry point (if form login is being used)</li>
|
|
|
+ * <li>If still ambiguous, throw an exception (for now). TODO: Examine additional beans and types and make decision</li>
|
|
|
* </ol>
|
|
|
*
|
|
|
*/
|
|
|
- private void configureAuthenticationEntryPoint(ConfigurableListableBeanFactory beanFactory) {
|
|
|
+ private void injectAuthenticationEntryPointIntoExceptionTranslationFilter(ConfigurableListableBeanFactory beanFactory) {
|
|
|
logger.info("Selecting AuthenticationEntryPoint for use in ExceptionTranslationFilter");
|
|
|
|
|
|
BeanDefinition etf =
|