From 5e3a0ef379443cbe9fc639cae1ffc109f936e3d2 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sat, 19 Jan 2008 13:51:03 +0000 Subject: [PATCH] SEC-632: Added user-filter element to namespace to allow a user to add their filters. Filters which aren't in the org.security.springframework package will now be skipped. Also renamed FilterChainOrderUtils and members for future use in ordering (e.g. using "after", "before" as attributes in user-filter). --- .../concurrent/ConcurrentSessionFilter.java | 4 +- .../security/config/Elements.java | 3 +- .../HttpSecurityConfigPostProcessor.java | 7 +- .../OrderedFilterBeanDefinitionDecorator.java | 74 +++++++++++++++++++ .../config/SecurityNamespaceHandler.java | 1 + .../HttpSessionContextIntegrationFilter.java | 4 +- .../web/FilterSecurityInterceptor.java | 4 +- .../anonymous/AnonymousProcessingFilter.java | 5 +- .../ChannelProcessingFilter.java | 4 +- .../ui/ExceptionTranslationFilter.java | 2 +- .../security/ui/FilterChainOrder.java | 34 +++++++++ .../security/ui/FilterChainOrderUtils.java | 34 --------- .../ui/basicauth/BasicProcessingFilter.java | 4 +- .../security/ui/cas/CasProcessingFilter.java | 6 +- .../security/ui/logout/LogoutFilter.java | 8 +- .../RememberMeProcessingFilter.java | 4 +- .../SwitchUserProcessingFilter.java | 4 +- .../AuthenticationProcessingFilter.java | 4 +- .../DefaultLoginPageGeneratingFilter.java | 4 +- ...curityContextHolderAwareRequestFilter.java | 4 +- .../security/config/spring-security-2.0.rnc | 9 +++ .../security/config/spring-security-2.0.xsd | 15 ++++ ...HttpSecurityBeanDefinitionParserTests.java | 4 +- .../security/config/http-security.xml | 9 +++ .../ui/ntlm/NtlmProcessingFilter.java | 4 +- 25 files changed, 182 insertions(+), 73 deletions(-) create mode 100644 core/src/main/java/org/springframework/security/config/OrderedFilterBeanDefinitionDecorator.java create mode 100644 core/src/main/java/org/springframework/security/ui/FilterChainOrder.java delete mode 100644 core/src/main/java/org/springframework/security/ui/FilterChainOrderUtils.java diff --git a/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java b/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java index db0d9b1b7b..2778f8dee6 100644 --- a/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java +++ b/core/src/main/java/org/springframework/security/concurrent/ConcurrentSessionFilter.java @@ -17,7 +17,7 @@ package org.springframework.security.concurrent; import org.springframework.security.Authentication; import org.springframework.security.context.SecurityContextHolder; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.security.ui.logout.LogoutHandler; import org.springframework.security.ui.logout.SecurityContextLogoutHandler; @@ -117,6 +117,6 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini } public int getOrder() { - return FilterChainOrderUtils.CONCURRENT_SESSION_FILTER_ORDER; + return FilterChainOrder.CONCURRENT_SESSION_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/config/Elements.java b/core/src/main/java/org/springframework/security/config/Elements.java index dbd92341e4..9bb7d73690 100644 --- a/core/src/main/java/org/springframework/security/config/Elements.java +++ b/core/src/main/java/org/springframework/security/config/Elements.java @@ -28,5 +28,6 @@ abstract class Elements { public static final String PASSWORD_ENCODER = "password-encoder"; public static final String SALT_SOURCE = "salt-source"; public static final String PORT_MAPPINGS = "port-mappings"; - public static final String PORT_MAPPING = "port-mapping"; + public static final String PORT_MAPPING = "port-mapping"; + public static final String USER_FILTER = "user-filter"; } diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java index d22f984b2b..aabcf32e5f 100644 --- a/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java +++ b/core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java @@ -183,9 +183,14 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor continue; } + // Filters must be Spring security filters or wrapped using + if (!filter.getClass().getName().startsWith("org.springframework.security")) { + continue; + } + if (!(filter instanceof Ordered)) { - // TODO: Possibly log this as a warning and skip this filter. logger.info("Filter " + id + " doesn't implement the Ordered interface, skipping it."); + continue; } orderedFilters.add(filter); diff --git a/core/src/main/java/org/springframework/security/config/OrderedFilterBeanDefinitionDecorator.java b/core/src/main/java/org/springframework/security/config/OrderedFilterBeanDefinitionDecorator.java new file mode 100644 index 0000000000..7a163ffccf --- /dev/null +++ b/core/src/main/java/org/springframework/security/config/OrderedFilterBeanDefinitionDecorator.java @@ -0,0 +1,74 @@ +package org.springframework.security.config; + +import org.springframework.beans.factory.xml.BeanDefinitionDecorator; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.core.Ordered; +import org.springframework.util.Assert; + +import org.w3c.dom.Node; +import org.w3c.dom.Element; + +import javax.servlet.Filter; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.FilterChain; +import java.io.IOException; + +/** + * Replaces a Spring bean of type "Filter" with a wrapper class which implement the Ordered + * interface. This allows user to add their own filter to the security chain. + * + * @author Luke Taylor + * @version $Id$ + */ +public class OrderedFilterBeanDefinitionDecorator implements BeanDefinitionDecorator { + public static final String ATT_ORDER = "order"; + + public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder holder, ParserContext parserContext) { + Element elt = (Element)node; + String order = elt.getAttribute(ATT_ORDER); + BeanDefinition filter = holder.getBeanDefinition(); + + Assert.hasText(order, "order attribute is required"); + + BeanDefinition wrapper = new RootBeanDefinition(OrderedFilterDecorator.class); + wrapper.getConstructorArgumentValues().addGenericArgumentValue(filter); + wrapper.getPropertyValues().addPropertyValue("order", order); + + return new BeanDefinitionHolder(wrapper, holder.getBeanName()); + } +} + +class OrderedFilterDecorator implements Filter, Ordered { + private int order = LOWEST_PRECEDENCE; + private Filter delegate; + + OrderedFilterDecorator(Filter delegate) { + this.delegate = delegate; + } + + public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + delegate.doFilter(request, response, chain); + } + + public final void init(FilterConfig filterConfig) throws ServletException { + delegate.init(filterConfig); + } + + public final void destroy() { + delegate.destroy(); + } + + public final int getOrder() { + return order; + } + + public final void setOrder(int order) { + this.order = order; + } +} diff --git a/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java b/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java index ce3ff270aa..8363caa5d6 100644 --- a/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java +++ b/core/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java @@ -24,5 +24,6 @@ public class SecurityNamespaceHandler extends NamespaceHandlerSupport { // Decorators registerBeanDefinitionDecorator(Elements.INTERCEPT_METHODS, new InterceptMethodsBeanDefinitionDecorator()); registerBeanDefinitionDecorator(Elements.FILTER_CHAIN_MAP, new FilterChainMapBeanDefinitionDecorator()); + registerBeanDefinitionDecorator(Elements.USER_FILTER, new OrderedFilterBeanDefinitionDecorator()); } } diff --git a/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java b/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java index 7c9080b211..ae71f79e39 100644 --- a/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java +++ b/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java @@ -31,7 +31,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; import org.springframework.security.ui.SpringSecurityFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; /** * Populates the {@link SecurityContextHolder} with information obtained from @@ -442,7 +442,7 @@ public class HttpSessionContextIntegrationFilter extends SpringSecurityFilter im } public int getOrder() { - return FilterChainOrderUtils.HTTP_SESSION_CONTEXT_FILTER_ORDER; + return FilterChainOrder.HTTP_SESSION_CONTEXT_FILTER; } //~ Inner Classes ================================================================================================== diff --git a/core/src/main/java/org/springframework/security/intercept/web/FilterSecurityInterceptor.java b/core/src/main/java/org/springframework/security/intercept/web/FilterSecurityInterceptor.java index 60320b70a9..92545023dc 100644 --- a/core/src/main/java/org/springframework/security/intercept/web/FilterSecurityInterceptor.java +++ b/core/src/main/java/org/springframework/security/intercept/web/FilterSecurityInterceptor.java @@ -18,7 +18,7 @@ package org.springframework.security.intercept.web; import org.springframework.security.intercept.AbstractSecurityInterceptor; import org.springframework.security.intercept.InterceptorStatusToken; import org.springframework.security.intercept.ObjectDefinitionSource; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.core.Ordered; import java.io.IOException; @@ -140,6 +140,6 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple } public int getOrder() { - return FilterChainOrderUtils.FILTER_SECURITY_INTERCEPTOR_ORDER; + return FilterChainOrder.FILTER_SECURITY_INTERCEPTOR; } } diff --git a/core/src/main/java/org/springframework/security/providers/anonymous/AnonymousProcessingFilter.java b/core/src/main/java/org/springframework/security/providers/anonymous/AnonymousProcessingFilter.java index c4384b5911..3a7e4c8bb4 100644 --- a/core/src/main/java/org/springframework/security/providers/anonymous/AnonymousProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/providers/anonymous/AnonymousProcessingFilter.java @@ -21,7 +21,7 @@ import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.ui.AuthenticationDetailsSource; import org.springframework.security.ui.AuthenticationDetailsSourceImpl; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.security.userdetails.memory.UserAttribute; @@ -36,7 +36,6 @@ import org.springframework.util.Assert; import java.io.IOException; import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -123,7 +122,7 @@ public class AnonymousProcessingFilter extends SpringSecurityFilter implements } public int getOrder() { - return FilterChainOrderUtils.ANON_PROCESSING_FILTER_ORDER; + return FilterChainOrder.ANON_PROCESSING_FILTER; } public String getKey() { diff --git a/core/src/main/java/org/springframework/security/securechannel/ChannelProcessingFilter.java b/core/src/main/java/org/springframework/security/securechannel/ChannelProcessingFilter.java index 47b489615b..04bbe46fc6 100644 --- a/core/src/main/java/org/springframework/security/securechannel/ChannelProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/securechannel/ChannelProcessingFilter.java @@ -20,7 +20,7 @@ import org.springframework.security.ConfigAttributeDefinition; import org.springframework.security.intercept.web.FilterInvocation; import org.springframework.security.intercept.web.FilterInvocationDefinitionSource; import org.springframework.security.ui.SpringSecurityFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; @@ -139,6 +139,6 @@ public class ChannelProcessingFilter extends SpringSecurityFilter implements Ini } public int getOrder() { - return FilterChainOrderUtils.CHANNEL_PROCESSING_FILTER_ORDER; + return FilterChainOrder.CHANNEL_PROCESSING_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/ExceptionTranslationFilter.java b/core/src/main/java/org/springframework/security/ui/ExceptionTranslationFilter.java index d539bdb0e1..9ce835bea4 100644 --- a/core/src/main/java/org/springframework/security/ui/ExceptionTranslationFilter.java +++ b/core/src/main/java/org/springframework/security/ui/ExceptionTranslationFilter.java @@ -236,6 +236,6 @@ public class ExceptionTranslationFilter extends SpringSecurityFilter implements } public int getOrder() { - return FilterChainOrderUtils.EXCEPTION_TRANSLATION_FILTER_ORDER; + return FilterChainOrder.EXCEPTION_TRANSLATION_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java b/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java new file mode 100644 index 0000000000..5234c93e20 --- /dev/null +++ b/core/src/main/java/org/springframework/security/ui/FilterChainOrder.java @@ -0,0 +1,34 @@ +package org.springframework.security.ui; + +import org.springframework.core.Ordered; + +/** + * Stores the default order numbers of all Spring Security filters for use in configuration. + * + * @author Luke Taylor + * @version $Id$ + */ +public abstract class FilterChainOrder { + /** + * The first position at which a Spring Security filter will be found. Any filter with an order less than this will + * be guaranteed to be placed before the Spring Security filters in the stack. + */ + public static final int FILTER_CHAIN_FIRST = Ordered.HIGHEST_PRECEDENCE + 1000; + private static final int INTERVAL = 100; + + public static final int CHANNEL_PROCESSING_FILTER = FILTER_CHAIN_FIRST + INTERVAL; + public static final int CONCURRENT_SESSION_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 2; + public static final int HTTP_SESSION_CONTEXT_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 3; + public static final int LOGOUT_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 4; + public static final int AUTH_PROCESSING_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 5; + public static final int CAS_PROCESSING_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 5; + public static final int LOGIN_PAGE_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 6; + public static final int BASIC_PROCESSING_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 7; + public static final int SECURITY_CONTEXT_HOLDER_AWARE_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 8; + public static final int REMEMBER_ME_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 9; + public static final int ANON_PROCESSING_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 10; + public static final int EXCEPTION_TRANSLATION_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 11; + public static final int NTLM_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 12; + public static final int FILTER_SECURITY_INTERCEPTOR = FILTER_CHAIN_FIRST + INTERVAL * 13; + public static final int SWITCH_USER_FILTER = FILTER_CHAIN_FIRST + INTERVAL * 14; +} diff --git a/core/src/main/java/org/springframework/security/ui/FilterChainOrderUtils.java b/core/src/main/java/org/springframework/security/ui/FilterChainOrderUtils.java deleted file mode 100644 index 11a2592eae..0000000000 --- a/core/src/main/java/org/springframework/security/ui/FilterChainOrderUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.springframework.security.ui; - -import org.springframework.core.Ordered; - -/** - * Stores the default order numbers of all Spring Security filters for use in configuration. - * - * @author luke - * @version $Id$ - */ -public abstract class FilterChainOrderUtils { - /** - * The first position at which a Spring Security filter will be found. Any filter with an order less than this will - * be guaranteed to be placed before the Spring Security filters in the stack. - */ - public static final int FILTER_CHAIN_FIRST = Ordered.HIGHEST_PRECEDENCE + 1000; - private static final int INTERVAL = 100; - - public static final int CHANNEL_PROCESSING_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL; - public static final int CONCURRENT_SESSION_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 2; - public static final int HTTP_SESSION_CONTEXT_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 3; - public static final int LOGOUT_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 4; - public static final int AUTH_PROCESSING_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 5; - public static final int CAS_PROCESSING_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 5; - public static final int LOGIN_PAGE_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 6; - public static final int BASIC_PROCESSING_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 7; - public static final int SECURITY_CONTEXT_HOLDER_AWARE_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 8; - public static final int REMEMBER_ME_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 9; - public static final int ANON_PROCESSING_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 10; - public static final int EXCEPTION_TRANSLATION_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 11; - public static final int NTLM_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 12; - public static final int FILTER_SECURITY_INTERCEPTOR_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 13; - public static final int SWITCH_USER_FILTER_ORDER = FILTER_CHAIN_FIRST + INTERVAL * 14; -} diff --git a/core/src/main/java/org/springframework/security/ui/basicauth/BasicProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/basicauth/BasicProcessingFilter.java index 6c2cb2d4df..bf84b8d53f 100644 --- a/core/src/main/java/org/springframework/security/ui/basicauth/BasicProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/basicauth/BasicProcessingFilter.java @@ -35,7 +35,7 @@ import org.springframework.security.providers.anonymous.AnonymousAuthenticationT import org.springframework.security.ui.AuthenticationDetailsSource; import org.springframework.security.ui.AuthenticationDetailsSourceImpl; import org.springframework.security.ui.AuthenticationEntryPoint; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.security.ui.rememberme.RememberMeServices; import org.springframework.util.Assert; @@ -223,6 +223,6 @@ public class BasicProcessingFilter extends SpringSecurityFilter implements Initi } public int getOrder() { - return FilterChainOrderUtils.BASIC_PROCESSING_FILTER_ORDER; + return FilterChainOrder.BASIC_PROCESSING_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java index eb3a75ccbc..29a617be9e 100644 --- a/core/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/cas/CasProcessingFilter.java @@ -21,10 +21,8 @@ import org.springframework.security.AuthenticationException; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.ui.AbstractProcessingFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -87,6 +85,6 @@ public class CasProcessingFilter extends AbstractProcessingFilter { } public int getOrder() { - return FilterChainOrderUtils.CAS_PROCESSING_FILTER_ORDER; + return FilterChainOrder.CAS_PROCESSING_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/logout/LogoutFilter.java b/core/src/main/java/org/springframework/security/ui/logout/LogoutFilter.java index 4c332e603b..f5a002bf0c 100644 --- a/core/src/main/java/org/springframework/security/ui/logout/LogoutFilter.java +++ b/core/src/main/java/org/springframework/security/ui/logout/LogoutFilter.java @@ -17,18 +17,14 @@ package org.springframework.security.ui.logout; import java.io.IOException; -import javax.servlet.Filter; import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.Authentication; import org.springframework.security.ui.SpringSecurityFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.util.RedirectUtils; import org.springframework.security.context.SecurityContextHolder; import org.apache.commons.logging.Log; @@ -158,6 +154,6 @@ public class LogoutFilter extends SpringSecurityFilter { } public int getOrder() { - return FilterChainOrderUtils.LOGOUT_FILTER_ORDER; + return FilterChainOrder.LOGOUT_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/rememberme/RememberMeProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/rememberme/RememberMeProcessingFilter.java index e2e840f1ef..2b9039b684 100644 --- a/core/src/main/java/org/springframework/security/ui/rememberme/RememberMeProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/rememberme/RememberMeProcessingFilter.java @@ -20,7 +20,7 @@ import org.springframework.security.AuthenticationException; import org.springframework.security.AuthenticationManager; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.event.authentication.InteractiveAuthenticationSuccessEvent; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationEventPublisher; @@ -159,6 +159,6 @@ public class RememberMeProcessingFilter extends SpringSecurityFilter implements } public int getOrder() { - return FilterChainOrderUtils.REMEMBER_ME_FILTER_ORDER; + return FilterChainOrder.REMEMBER_ME_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/switchuser/SwitchUserProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/switchuser/SwitchUserProcessingFilter.java index 9dfc6a1403..98e2c11f89 100644 --- a/core/src/main/java/org/springframework/security/ui/switchuser/SwitchUserProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/switchuser/SwitchUserProcessingFilter.java @@ -35,7 +35,7 @@ import org.springframework.security.providers.UsernamePasswordAuthenticationToke import org.springframework.security.ui.AuthenticationDetailsSource; import org.springframework.security.ui.AuthenticationDetailsSourceImpl; import org.springframework.security.ui.SpringSecurityFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.AbstractProcessingFilter; import org.springframework.security.userdetails.UserDetails; @@ -482,6 +482,6 @@ public class SwitchUserProcessingFilter extends SpringSecurityFilter implements } public int getOrder() { - return FilterChainOrderUtils.SWITCH_USER_FILTER_ORDER; + return FilterChainOrder.SWITCH_USER_FILTER; } } diff --git a/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java b/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java index 147a11c172..9c6cb01997 100644 --- a/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java @@ -21,7 +21,7 @@ import org.springframework.security.AuthenticationException; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.ui.AbstractProcessingFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest; @@ -154,7 +154,7 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter { } public int getOrder() { - return FilterChainOrderUtils.AUTH_PROCESSING_FILTER_ORDER; + return FilterChainOrder.AUTH_PROCESSING_FILTER; } String getUsernameParameter() { diff --git a/core/src/main/java/org/springframework/security/ui/webapp/DefaultLoginPageGeneratingFilter.java b/core/src/main/java/org/springframework/security/ui/webapp/DefaultLoginPageGeneratingFilter.java index d83ad7a93a..ffa9eb1270 100644 --- a/core/src/main/java/org/springframework/security/ui/webapp/DefaultLoginPageGeneratingFilter.java +++ b/core/src/main/java/org/springframework/security/ui/webapp/DefaultLoginPageGeneratingFilter.java @@ -10,7 +10,7 @@ import javax.servlet.http.HttpSession; import org.springframework.security.AuthenticationException; import org.springframework.security.ui.AbstractProcessingFilter; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.security.ui.rememberme.AbstractRememberMeServices; @@ -89,7 +89,7 @@ public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter { } public int getOrder() { - return FilterChainOrderUtils.LOGIN_PAGE_FILTER_ORDER; + return FilterChainOrder.LOGIN_PAGE_FILTER; } private boolean isLoginUrlRequest(HttpServletRequest request) { diff --git a/core/src/main/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestFilter.java b/core/src/main/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestFilter.java index e83445650f..d13d51be35 100644 --- a/core/src/main/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestFilter.java +++ b/core/src/main/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestFilter.java @@ -23,7 +23,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.security.util.PortResolver; import org.springframework.security.util.PortResolverImpl; @@ -92,6 +92,6 @@ public class SecurityContextHolderAwareRequestFilter extends SpringSecurityFilte } public int getOrder() { - return FilterChainOrderUtils.SECURITY_CONTEXT_HOLDER_AWARE_FILTER_ORDER; + return FilterChainOrder.SECURITY_CONTEXT_HOLDER_AWARE_FILTER; } } diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc index 75fdfcb36b..2da757dfc5 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.rnc @@ -258,3 +258,12 @@ jdbc-user-service = jdbc-user-service.attlist &= ## The bean ID of the DataSource which provides the required tables. attribute data-source {xsd:string} + + +user-filter = + ## Used to indicate that a filter bean declaration should be incorporated into the security filter chain. + element user-filter {user-filter.attlist} +user-filter.attlist &= + ## The order value for the chain (user to position the filter relative to the standard filters) + attribute order {xsd:integer} + diff --git a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd index 20a71215e8..4d7bb8830c 100644 --- a/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd +++ b/core/src/main/resources/org/springframework/security/config/spring-security-2.0.xsd @@ -629,4 +629,19 @@ + + + Used to indicate that a filter bean declaration should be incorporated into the security filter chain. + + + + + + + + + The order value for the chain (user to position the filter relative to the standard filters) + + + diff --git a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java index 08cb0f7f37..3e3800cfc4 100644 --- a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java +++ b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java @@ -12,6 +12,7 @@ import org.springframework.security.ui.webapp.AuthenticationProcessingFilter; import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter; import org.springframework.security.util.FilterChainProxy; import org.springframework.security.util.PortMapperImpl; +import org.springframework.security.util.MockFilter; import org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.beans.BeansException; @@ -65,7 +66,7 @@ public class HttpSecurityBeanDefinitionParserTests { List filterList = filterChainProxy.getFilters("/someurl"); - assertEquals("Expected 11 filters in chain", 11, filterList.size()); + assertEquals("Expected 12 filters in chain", 12, filterList.size()); Iterator filters = filterList.iterator(); @@ -80,6 +81,7 @@ public class HttpSecurityBeanDefinitionParserTests { assertTrue(filters.next() instanceof RememberMeProcessingFilter); assertTrue(filters.next() instanceof ExceptionTranslationFilter); assertTrue(filters.next() instanceof FilterSecurityInterceptor); + assertTrue(filters.next() instanceof OrderedFilterDecorator); } diff --git a/core/src/test/resources/org/springframework/security/config/http-security.xml b/core/src/test/resources/org/springframework/security/config/http-security.xml index 86bfd99916..e4b0577c27 100644 --- a/core/src/test/resources/org/springframework/security/config/http-security.xml +++ b/core/src/test/resources/org/springframework/security/config/http-security.xml @@ -40,4 +40,13 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc + + + + + + + + + \ No newline at end of file diff --git a/ntlm/src/main/java/org/springframework/security/ui/ntlm/NtlmProcessingFilter.java b/ntlm/src/main/java/org/springframework/security/ui/ntlm/NtlmProcessingFilter.java index 12b9cea150..0bcbdb21f0 100755 --- a/ntlm/src/main/java/org/springframework/security/ui/ntlm/NtlmProcessingFilter.java +++ b/ntlm/src/main/java/org/springframework/security/ui/ntlm/NtlmProcessingFilter.java @@ -26,7 +26,7 @@ import org.springframework.security.providers.UsernamePasswordAuthenticationToke import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken; import org.springframework.security.ui.SpringSecurityFilter; import org.springframework.security.ui.WebAuthenticationDetails; -import org.springframework.security.ui.FilterChainOrderUtils; +import org.springframework.security.ui.FilterChainOrder; import org.springframework.security.ui.webapp.AuthenticationProcessingFilter; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; @@ -497,6 +497,6 @@ public class NtlmProcessingFilter extends SpringSecurityFilter implements Initia } public int getOrder() { - return FilterChainOrderUtils.NTLM_FILTER_ORDER; + return FilterChainOrder.NTLM_FILTER; } }