Announcement Announcement Module
Collapse
No announcement yet.
<sec:remember-me> service-ref attribute required to be LogoutHandler? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • <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.

  • #2
    I guess some clarification is required one way or the other. The problem is that the namespace probably won't know whether the bean implements LogoutHandler or not when it makes the decision on whether to inject the RememberMeServices into the logout filter. If we choose not to, then the user may be forced to explicitly add and configure a LogoutFilter if they use a custom RememberMeServices.

    Probably the best option would be to document clearly that an implementation must also implement LogoutHandler if you are using the namespace logout support. It can always be a null implementation.

    Another possibility is to use a factory bean to do the injection and check the type, but I'd prefer to avoid complicating things to that extent.

    Comment

    Working...
    X