SEC-271: Fixed IllegalStateException being thrown by LogoutHandlerOrdereResolver and add an assert statement in the unit test
This commit is contained in:
parent
a01bb3bbee
commit
a934f82af4
|
@ -67,17 +67,21 @@ public class LogoutHandlerOrderResolver implements BeanFactoryPostProcessor {
|
||||||
for (int i = 0, n = names.length; i < n; i++) {
|
for (int i = 0, n = names.length; i < n; i++) {
|
||||||
RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[i]);
|
RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[i]);
|
||||||
|
|
||||||
if (Ordered.class.isAssignableFrom(definition.getBeanClass())) {
|
if (definition.hasBeanClass()) {
|
||||||
definition.getPropertyValues().addPropertyValue("order", new Integer(getOrder(definition.getBeanClass())));
|
if (Ordered.class.isAssignableFrom(definition.getBeanClass())) {
|
||||||
} else {
|
definition.getPropertyValues().addPropertyValue("order",
|
||||||
definition.getPropertyValues().addPropertyValue("order", new Integer(Integer.MAX_VALUE));
|
new Integer(getOrder(definition.getBeanClass())));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
definition.getPropertyValues().addPropertyValue("order", new Integer(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
list.add(definition);
|
list.add(definition);
|
||||||
}
|
}
|
||||||
Collections.sort(list, new OrderComparator());
|
Collections.sort(list, new OrderComparator());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getOrder(Class clazz) {
|
private int getOrder(Class clazz) {
|
||||||
if (clazz.getName().equals(TokenBasedRememberMeServices.class.getName())) {
|
if (clazz.getName().equals(TokenBasedRememberMeServices.class.getName())) {
|
||||||
return 100;
|
return 100;
|
||||||
|
|
|
@ -3,19 +3,27 @@
|
||||||
*/
|
*/
|
||||||
package org.acegisecurity.config;
|
package org.acegisecurity.config;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import java.util.Map;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.acegisecurity.ui.logout.LogoutHandler;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author vpuri
|
* @author vpuri
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class LogoutFilterBeanDefinitionParserTests extends TestCase {
|
public class LogoutFilterBeanDefinitionParserTests extends TestCase {
|
||||||
|
|
||||||
public void testLogoutFilter(){
|
public void testLogoutFilter() {
|
||||||
ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/logout-filter-with-handlers.xml");
|
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||||
|
"org/acegisecurity/config/logout-filter-with-handlers.xml");
|
||||||
|
ConfigurableListableBeanFactory bf = (ConfigurableListableBeanFactory) context.getAutowireCapableBeanFactory();
|
||||||
|
Map m = bf.getBeansOfType(LogoutHandler.class);
|
||||||
|
assertEquals(2, m.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,14 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
|
||||||
<!-- If LogoutFilter does not have setHandlers populated, introspect app ctx for LogoutHandlers, using Ordered (if present, otherwise assume Integer.MAX_VALUE) -->
|
<!-- If LogoutFilter does not have setHandlers populated, introspect app ctx for LogoutHandlers, using Ordered (if present, otherwise assume Integer.MAX_VALUE) -->
|
||||||
<!-- The logoutUrl and redirectAfterLogout are both optional and default to that shown -->
|
<!-- The logoutUrl and redirectAfterLogout are both optional and default to that shown -->
|
||||||
<security:logout-support id="logoutFilter"
|
<security:logout-support id="logoutFilter"
|
||||||
redirectAfterLogoutUrl="/" logoutUrl="/logout"/>
|
redirectAfterLogoutUrl="/" logoutUrl="/logout" />
|
||||||
|
|
||||||
<security:authentication-remember-me-services
|
<security:authentication-remember-me-services
|
||||||
id="rememberMeServices" key="someValue" />
|
id="rememberMeServices" key="someValue" />
|
||||||
|
|
||||||
|
<bean id="SecurityContextLogoutHandler"
|
||||||
|
class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
|
||||||
|
|
||||||
<security:principal-repository id="userDetailsService">
|
<security:principal-repository id="userDetailsService">
|
||||||
<security:user-definition username="vishal"
|
<security:user-definition username="vishal"
|
||||||
password="nottellingya" enabled="true">
|
password="nottellingya" enabled="true">
|
||||||
|
|
|
@ -1,148 +1,174 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
<!--
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
- A simple "base bones" Acegi Security configuration.
|
xmlns:security="http://www.springframework.org/schema/security"
|
||||||
-
|
xmlns:util="http://www.springframework.org/schema/util"
|
||||||
- The sample includes the "popular" features that people tend to use.
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||||
- Specifically, form authentication, remember-me, and anonymous processing.
|
http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
|
||||||
- Other features aren't setup, as these can be added later by inserting
|
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
|
||||||
- the relevant XML fragments as specified in the Reference Guide.
|
|
||||||
-
|
<!--
|
||||||
- To assist new users, the filters specified in the FilterChainProxy are
|
- A simple "base bones" Acegi Security configuration.
|
||||||
- declared in the application context in the same order. Collaborators
|
-
|
||||||
- required by those filters are placed at the end of the file.
|
- The sample includes the "popular" features that people tend to use.
|
||||||
-
|
- Specifically, form authentication, remember-me, and anonymous processing.
|
||||||
- $Id$
|
- Other features aren't setup, as these can be added later by inserting
|
||||||
-->
|
- the relevant XML fragments as specified in the Reference Guide.
|
||||||
|
-
|
||||||
<beans>
|
- To assist new users, the filters specified in the FilterChainProxy are
|
||||||
|
- declared in the application context in the same order. Collaborators
|
||||||
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
|
- required by those filters are placed at the end of the file.
|
||||||
<property name="filterInvocationDefinitionSource">
|
-
|
||||||
<value>
|
- $Id$
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
-->
|
||||||
PATTERN_TYPE_APACHE_ANT
|
|
||||||
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
|
|
||||||
</value>
|
|
||||||
</property>
|
<bean id="filterChainProxy"
|
||||||
</bean>
|
class="org.acegisecurity.util.FilterChainProxy">
|
||||||
|
<property name="filterInvocationDefinitionSource">
|
||||||
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
|
<value>
|
||||||
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
|
PATTERN_TYPE_APACHE_ANT
|
||||||
<constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout -->
|
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
|
||||||
<constructor-arg>
|
</value>
|
||||||
<list>
|
</property>
|
||||||
<ref bean="rememberMeServices"/>
|
</bean>
|
||||||
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
|
|
||||||
</list>
|
<!-- sessionCreation defaults to ifRequired(true) always(true) never(false) . -->
|
||||||
</constructor-arg>
|
<security:session-context-integration
|
||||||
</bean>
|
id="httpSessionContextIntegrationFilter" sessionCreation="ifRequired" />
|
||||||
|
|
||||||
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
|
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
<!-- If LogoutFilter does not have setHandlers populated, introspect app ctx for LogoutHandlers, using Ordered (if present, otherwise assume Integer.MAX_VALUE) -->
|
||||||
<property name="authenticationFailureUrl" value="/acegilogin.jsp?login_error=1"/>
|
<!-- The logoutUrl and redirectAfterLogout are both optional and default to that shown -->
|
||||||
<property name="defaultTargetUrl" value="/"/>
|
<security:logout-support id="logoutFilter"
|
||||||
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
|
redirectAfterLogoutUrl="/index.jsp" />
|
||||||
<property name="rememberMeServices" ref="rememberMeServices"/>
|
|
||||||
</bean>
|
<security:authentication-remember-me-services
|
||||||
|
id="rememberMeServices" key="someValue" />
|
||||||
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
|
|
||||||
|
|
||||||
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
|
<bean id="securityContextLogoutHandler"
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
|
||||||
<property name="rememberMeServices" ref="rememberMeServices"/>
|
|
||||||
</bean>
|
<!-- the URLs are all mandatory and have no defaults (well, except authenticationUrl) -->
|
||||||
|
<security:authentication-form id="authenticationProcessinFilter"
|
||||||
<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
|
authenticationUrl="/j_acegi_security_check" defaultTargetUrl="/"
|
||||||
<property name="key" value="changeThis"/>
|
errorFormUrl="/acegilogin.jsp?login_error=1" />
|
||||||
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
|
|
||||||
</bean>
|
<!-- make it optional, if not supplied autodetect all auth-providers from app ctx, using Ordered to resolve their order -->
|
||||||
|
<security:authentication-mechanism id="authenticationManager" />
|
||||||
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
|
|
||||||
<property name="authenticationEntryPoint">
|
<!-- dao authentication provider "authenticationRepository" -->
|
||||||
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
|
<security:authentication-repository id="daoAuthenticationProvider" />
|
||||||
<property name="loginFormUrl" value="/acegilogin.jsp"/>
|
|
||||||
<property name="forceHttps" value="false"/>
|
<bean id="securityContextHolderAwareRequestFilter"
|
||||||
</bean>
|
class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />
|
||||||
</property>
|
|
||||||
<property name="accessDeniedHandler">
|
<!-- makes the filter, but does little else, as it auto-detects everything -->
|
||||||
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
|
<security:authentication-remember-me-filter id="rememberMeFilter" />
|
||||||
<property name="errorPage" value="/accessDenied.jsp"/>
|
|
||||||
</bean>
|
<bean id="anonymousProcessingFilter"
|
||||||
</property>
|
class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
|
||||||
</bean>
|
<property name="key" value="changeThis" />
|
||||||
|
<property name="userAttribute"
|
||||||
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
|
value="anonymousUser,ROLE_ANONYMOUS" />
|
||||||
<property name="authenticationManager" ref="authenticationManager"/>
|
</bean>
|
||||||
<property name="accessDecisionManager">
|
|
||||||
<bean class="org.acegisecurity.vote.AffirmativeBased">
|
<!-- Basically accessDeniedUrl is optional, we if unspecified impl will auto-detect any AccessDeniedHandler in ctx and use it;
|
||||||
<property name="allowIfAllAbstainDecisions" value="false"/>
|
alternately if there are > 1 such handlers, we can nominate the one to use via accessDeniedBeanRef; provide nested elements for
|
||||||
<property name="decisionVoters">
|
other props; i do not mind if you move the access denied stuff to a sub-element -->
|
||||||
<list>
|
<security:exception-translation id="exceptionTranslationFilter">
|
||||||
<bean class="org.acegisecurity.vote.RoleVoter"/>
|
<security:entry-point
|
||||||
<bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
|
entryPointBeanRef="authenticationEntryPoint" />
|
||||||
</list>
|
</security:exception-translation>
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
</property>
|
<bean id="authenticationEntryPoint"
|
||||||
<property name="objectDefinitionSource">
|
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
|
||||||
<value>
|
<property name="loginFormUrl" value="/acegilogin.jsp" />
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
<property name="forceHttps" value="false" />
|
||||||
PATTERN_TYPE_APACHE_ANT
|
</bean>
|
||||||
/secure/extreme/**=ROLE_SUPERVISOR
|
|
||||||
/secure/**=IS_AUTHENTICATED_REMEMBERED
|
|
||||||
/**=IS_AUTHENTICATED_ANONYMOUSLY
|
<bean id="accessDeniedHandler"
|
||||||
</value>
|
class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
|
||||||
</property>
|
<property name="errorPage" value="/accessDenied.jsp" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
|
|
||||||
<property name="userDetailsService" ref="userDetailsService"/>
|
<bean id="filterInvocationInterceptor"
|
||||||
<property name="key" value="changeThis"/>
|
class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
|
||||||
</bean>
|
<property name="authenticationManager"
|
||||||
|
ref="authenticationManager" />
|
||||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
<property name="accessDecisionManager">
|
||||||
<property name="providers">
|
<bean class="org.acegisecurity.vote.AffirmativeBased">
|
||||||
<list>
|
<property name="allowIfAllAbstainDecisions"
|
||||||
<ref local="daoAuthenticationProvider"/>
|
value="false" />
|
||||||
<bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
|
<property name="decisionVoters">
|
||||||
<property name="key" value="changeThis"/>
|
<list>
|
||||||
</bean>
|
<bean class="org.acegisecurity.vote.RoleVoter" />
|
||||||
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
|
<bean
|
||||||
<property name="key" value="changeThis"/>
|
class="org.acegisecurity.vote.AuthenticatedVoter" />
|
||||||
</bean>
|
</list>
|
||||||
</list>
|
</property>
|
||||||
</property>
|
</bean>
|
||||||
</bean>
|
</property>
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
<value>
|
||||||
<property name="userDetailsService" ref="userDetailsService"/>
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
<property name="userCache">
|
PATTERN_TYPE_APACHE_ANT
|
||||||
<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
|
/secure/extreme/**=ROLE_SUPERVISOR
|
||||||
<property name="cache">
|
/secure/**=IS_AUTHENTICATED_REMEMBERED
|
||||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
/**=IS_AUTHENTICATED_ANONYMOUSLY
|
||||||
<property name="cacheManager">
|
</value>
|
||||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
</property>
|
||||||
</property>
|
</bean>
|
||||||
<property name="cacheName" value="userCache"/>
|
|
||||||
</bean>
|
|
||||||
</property>
|
<!--<bean id="authenticationManager"
|
||||||
</bean>
|
class="org.acegisecurity.providers.ProviderManager">
|
||||||
</property>
|
<property name="providers">
|
||||||
</bean>
|
<list>
|
||||||
|
<ref local="daoAuthenticationProvider" />
|
||||||
<!-- UserDetailsService is the most commonly frequently Acegi Security interface implemented by end users -->
|
<bean
|
||||||
<bean id="userDetailsService" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
|
||||||
<property name="userProperties">
|
<property name="key" value="changeThis" />
|
||||||
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
</bean>
|
||||||
<property name="location" value="/WEB-INF/users.properties"/>
|
<bean
|
||||||
</bean>
|
class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
|
||||||
</property>
|
<property name="key" value="changeThis" />
|
||||||
</bean>
|
</bean>
|
||||||
|
</list>
|
||||||
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
|
</property>
|
||||||
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
|
</bean>-->
|
||||||
|
|
||||||
|
<bean id="userCache"
|
||||||
|
class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
|
||||||
|
<property name="cache">
|
||||||
|
<bean
|
||||||
|
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||||
|
<property name="cacheManager">
|
||||||
|
<bean
|
||||||
|
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
|
||||||
|
</property>
|
||||||
|
<property name="cacheName" value="userCache" />
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- UserDetailsService is the most commonly frequently Acegi Security interface implemented by end users -->
|
||||||
|
|
||||||
|
<security:principal-repository id="userDetailsService">
|
||||||
|
<security:properties resource="/WEB-INF/users.properties" />
|
||||||
|
</security:principal-repository>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
|
||||||
|
<bean id="loggerListener"
|
||||||
|
class="org.acegisecurity.event.authentication.LoggerListener" />
|
||||||
|
|
||||||
</beans>
|
</beans>
|
Loading…
Reference in New Issue