<sec:remember-me> service-ref attribute required to be LogoutHandler?
If the <remember-me> services-ref specifies an implementation of the RememberMeServices interface that does not also implement LogoutHandler I get an Exception. A specific example of the configuration and exception is below.
When using the configuration:
Code:
<http auto-config="true">
<remember-me key="ourkey" services-ref="rms" />
</http>
<b:bean id="rms"
class="org.springframework.security.web.authentication.NullRememberMeServices" />
<authentication-manager>
<authentication-provider>
<user-service>
<user name="un" password="pwd" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
I get the following Exception:
Code:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Cannot create inner bean '(inner bean)' of type [org.springframework.security.web.authentication.logout.LogoutFilter] while setting bean property 'filterChainMap' with key [Root bean: class [java.lang.String]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [1]; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '(inner bean)#10': Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.security.web.authentication.logout.LogoutHandler[]]: Could not convert constructor argument value of type [java.util.ArrayList] to required type [[Lorg.springframework.security.web.authentication.logout.LogoutHandler;]: Failed to convert value of type 'java.util.ArrayList' to required type 'org.springframework.security.web.authentication.logout.LogoutHandler[]'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.web.authentication.NullRememberMeServices] to required type [org.springframework.security.web.authentication.logout.LogoutHandler]: no matching editors or conversion strategy found
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '(inner bean)#10': Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.security.web.authentication.logout.LogoutSuccessHandler]: Could not convert constructor argument value of type [java.lang.String] to required type [org.springframework.security.web.authentication.logout.LogoutSuccessHandler]: Failed to convert value of type 'java.lang.String' to required type 'org.springframework.security.web.authentication.logout.LogoutSuccessHandler'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.security.web.authentication.logout.LogoutSuccessHandler]: no matching editors or conversion strategy found
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:355)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:383)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:161)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1317)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
... 24 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '(inner bean)#10': Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.security.web.authentication.logout.LogoutHandler[]]: Could not convert constructor argument value of type [java.util.ArrayList] to required type [[Lorg.springframework.security.web.authentication.logout.LogoutHandler;]: Failed to convert value of type 'java.util.ArrayList' to required type 'org.springframework.security.web.authentication.logout.LogoutHandler[]'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.web.authentication.NullRememberMeServices] to required type [org.springframework.security.web.authentication.logout.LogoutHandler]: no matching editors or conversion strategy found
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:690)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:194)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:993)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:897)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270)
... 44 more
I realize that the other RememberMeServices implement LogoutHandler and this is probably why the namespace is trying to wire the NullRememberMeServices into the LogoutFilter. However, I wanted to know if the namespace behavior is a bug or if the services-ref is required to implement RememberMeServices and LogoutHandler. I really hope that services-ref is not required to implement LogoutHandler as the namespace then seems to imply that RememberMeServices is a LogoutHandler which is not reflected in the class hiarachy. However, if it services-ref is required to be a LogoutHandler too, it would be nice to specify this in the xsd and in the reference guide.
Any clarity on the expected behavior would be greatly appreciated.
Thanks,
Rob
PS: I understand that is silly to reference the NullRememberMeServices, but thought it would simplify the example. In reality I was using my own custom RememberMeServices implementation that does not need to do anything on Logout.