mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	SEC-1210: RememberMe filter misses UserDetailsService in default <http /> tag config when it is declared in parent app context. Fixed by getting the UserDetailsServiceInjectionPostProcessor to check ancestor bean factories for a UserDetailsService if one isn't found in the current bean factory.
This commit is contained in:
		
							parent
							
								
									160aa512a1
								
							
						
					
					
						commit
						c5d6484b54
					
				| @ -7,6 +7,8 @@ import org.springframework.beans.BeansException; | |||||||
| import org.springframework.beans.PropertyValue; | import org.springframework.beans.PropertyValue; | ||||||
| import org.springframework.beans.factory.BeanFactory; | import org.springframework.beans.factory.BeanFactory; | ||||||
| import org.springframework.beans.factory.BeanFactoryAware; | import org.springframework.beans.factory.BeanFactoryAware; | ||||||
|  | import org.springframework.beans.factory.HierarchicalBeanFactory; | ||||||
|  | import org.springframework.beans.factory.ListableBeanFactory; | ||||||
| import org.springframework.beans.factory.config.BeanDefinition; | import org.springframework.beans.factory.config.BeanDefinition; | ||||||
| import org.springframework.beans.factory.config.BeanPostProcessor; | import org.springframework.beans.factory.config.BeanPostProcessor; | ||||||
| import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | ||||||
| @ -108,16 +110,15 @@ public class UserDetailsServiceInjectionBeanPostProcessor implements BeanPostPro | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Obtains a user details service for use in RememberMeServices etc. Will return a caching version |      * Obtains a user details service for use in RememberMeServices etc. Will return a caching version | ||||||
|      * if available so should not be used for beans which need to separate the two. |      * if available so should not be used for beans which need to separate the two. | ||||||
|      */ |      */ | ||||||
|     UserDetailsService getUserDetailsService() { |     UserDetailsService getUserDetailsService() { | ||||||
|         Map<String,?> beans = beanFactory.getBeansOfType(CachingUserDetailsService.class); |         Map<String,?> beans = getBeansOfType(CachingUserDetailsService.class); | ||||||
| 
 | 
 | ||||||
|         if (beans.size() == 0) { |         if (beans.size() == 0) { | ||||||
|             beans = beanFactory.getBeansOfType(UserDetailsService.class); |             beans = getBeansOfType(UserDetailsService.class); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (beans.size() == 0) { |         if (beans.size() == 0) { | ||||||
| @ -146,6 +147,25 @@ public class UserDetailsServiceInjectionBeanPostProcessor implements BeanPostPro | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private Map<String,?> getBeansOfType(Class<?> type) { | ||||||
|  |         Map<String,?> beans = beanFactory.getBeansOfType(type); | ||||||
|  | 
 | ||||||
|  |         // Check ancestor bean factories if they exist and the current one has none of the required type | ||||||
|  |         BeanFactory parent = beanFactory.getParentBeanFactory(); | ||||||
|  |         while (parent != null && beans.size() == 0) { | ||||||
|  |             if (parent instanceof ListableBeanFactory) { | ||||||
|  |                 beans = ((ListableBeanFactory)parent).getBeansOfType(type); | ||||||
|  |             } | ||||||
|  |             if (parent instanceof HierarchicalBeanFactory) { | ||||||
|  |                 parent = ((HierarchicalBeanFactory)parent).getParentBeanFactory(); | ||||||
|  |             } else { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return beans; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |     public void setBeanFactory(BeanFactory beanFactory) throws BeansException { | ||||||
|         this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; |         this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; | ||||||
|  | |||||||
| @ -938,6 +938,16 @@ public class HttpSecurityBeanDefinitionParserTests { | |||||||
|         assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(filter, "repo.disableUrlRewriting")); |         assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(filter, "repo.disableUrlRewriting")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Test | ||||||
|  |     public void userDetailsServiceInParentContextIsLocatedSuccessfully() throws Exception { | ||||||
|  |         appContext = new InMemoryXmlApplicationContext(AUTH_PROVIDER_XML); | ||||||
|  | 
 | ||||||
|  |         appContext = new InMemoryXmlApplicationContext( | ||||||
|  |                 "<http auto-config='true'>" + | ||||||
|  |                 "    <remember-me />" + | ||||||
|  |                 "</http>", appContext); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private void setContext(String context) { |     private void setContext(String context) { | ||||||
|         appContext = new InMemoryXmlApplicationContext(context); |         appContext = new InMemoryXmlApplicationContext(context); | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user