Przeglądaj źródła

SEC-271: removed autowiring by type and explicity introspected the applicationContext to detect the required dependencies of userDetailsService

Vishal Puri 18 lat temu
rodzic
commit
e3435da9ae

+ 10 - 5
core/src/main/java/org/acegisecurity/config/AuthenticationProviderOrderResolver.java

@@ -1,15 +1,16 @@
 package org.acegisecurity.config;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 import org.acegisecurity.AuthenticationManager;
 import org.acegisecurity.providers.AuthenticationProvider;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.ManagedList;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 import org.springframework.core.OrderComparator;
 
@@ -20,7 +21,7 @@ public class AuthenticationProviderOrderResolver implements BeanFactoryPostProce
 	 */
 	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 		// retrieve all the AuthenticationProvider instances
-		List providers = retrieveAllAuthenticationProviders(beanFactory);
+		ManagedList providers = retrieveAllAuthenticationProviders(beanFactory);
 		String[] names = beanFactory.getBeanNamesForType(AuthenticationManager.class);
 		RootBeanDefinition definition = (RootBeanDefinition)beanFactory.getBeanDefinition(names[0]);
 		definition.getPropertyValues().addPropertyValue("providers",providers);
@@ -30,9 +31,13 @@ public class AuthenticationProviderOrderResolver implements BeanFactoryPostProce
 	 * @param beanFactory
 	 * @return
 	 */
-	private List retrieveAllAuthenticationProviders(ConfigurableListableBeanFactory beanFactory) {
-		Map m = beanFactory.getBeansOfType(AuthenticationProvider.class);
-		List l = new ArrayList(m.values());
+	private ManagedList retrieveAllAuthenticationProviders(ConfigurableListableBeanFactory beanFactory) {
+		String[] m = beanFactory.getBeanNamesForType(AuthenticationProvider.class);
+		ManagedList l = new ManagedList();
+		for(int i=0;i<m.length;i++){
+			RootBeanDefinition def = (RootBeanDefinition)beanFactory.getBeanDefinition(m[i]);
+			l.add(def);
+		}
 		Collections.sort(l, new OrderComparator());
 		return l;
 	}

+ 56 - 51
core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java

@@ -7,6 +7,7 @@ import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
 import org.acegisecurity.providers.dao.salt.ReflectionSaltSource;
 import org.acegisecurity.providers.dao.salt.SystemWideSaltSource;
 import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
 import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -23,9 +24,10 @@ import org.w3c.dom.NodeList;
  * @author vpuri
  * 
  */
-public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDefinitionParser   {
+public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDefinitionParser {
 
-	//	~ Instance fields ================================================================================================
+	// ~ Instance fields
+	// ================================================================================================
 
 	private static final String REPOSITORY_BEAN_REF = "repositoryBeanRef";
 
@@ -38,26 +40,30 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe
 	private static final String SYSTEM_WIDE_SALT_SOURCE = "system-wide";
 
 	private static final String REFLECTION_SALT_SOURCE = "reflection";
-	
+
 	private static final String PASSWORD_ENCODER_ELEMENT = "password-encoder";
-	
+
 	private static final String PASSWORD_ENCODER_REF = "encoderBeanRef";
-	
+
 	private static final String PASSWORD_ENCODER = "encoder";
-	
-	public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect";
-	
-	
-	
-	//	~ Method ================================================================================================
+
+	// ~ Method
+	// ================================================================================================
 	/**
 	 * TODO: Document Me !!!
 	 */
 	public AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
 		Assert.notNull(parserContext, "ParserContext must not be null");
-		
+
 		RootBeanDefinition repositoryBeanDef = new RootBeanDefinition(DaoAuthenticationProvider.class);
 		
+		// check if saltSource is defined
+		Element saltSourceEle = DomUtils.getChildElementByTagName(element, SALT_SOURCE_ELEMENT);
+		setSaltSourceProperty(repositoryBeanDef, saltSourceEle);
+
+		Element passwordEncoderEle = DomUtils.getChildElementByTagName(element, PASSWORD_ENCODER_ELEMENT);
+		setPasswordEncoderProperty(repositoryBeanDef, passwordEncoderEle);
+
 		// if repositoryBeanRef is specified use its referred bean
 		String userDetailsRef = element.getAttribute(REPOSITORY_BEAN_REF);
 		if (StringUtils.hasLength(userDetailsRef)) {
@@ -65,41 +71,39 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe
 					new RuntimeBeanReference(userDetailsRef));
 		}
 		else {
-			// autodetect userDetailsService from App Context ? or we could even create this UserDetailsService BD with autodetection of dataSource hahaha Magic !!!
-			//repositoryBeanDef.getPropertyValues().addPropertyValue(USER_DETAILS_SERVICE,		new RuntimeBeanReference(USER_DETAILS_SERVICE));
-			repositoryBeanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT);
+			// autodetect userDetailsService from App Context
+			RootBeanDefinition depConfigurer = new RootBeanDefinition(
+					AuthenticationRepositoryDependenciesConfigurer.class);
+			BeanDefinitionHolder holder = new BeanDefinitionHolder(depConfigurer, parserContext.getReaderContext().generateBeanName(depConfigurer));
+			registerBeanDefinition(holder, parserContext.getRegistry());
 		}
-		//	check if saltSource is defined
-		Element saltSourceEle = DomUtils.getChildElementByTagName(element, SALT_SOURCE_ELEMENT);
-		setSaltSourceProperty(repositoryBeanDef, saltSourceEle);
-		
-		Element passwordEncoderEle = DomUtils.getChildElementByTagName(element, PASSWORD_ENCODER_ELEMENT);
-		setPasswordEncoderProperty(repositoryBeanDef, passwordEncoderEle);
-		
 		return repositoryBeanDef;
 	}
-	
+
 	/**
 	 * 
 	 * @param repositoryBeanDef
 	 * @param element
 	 */
 	private void setSaltSourceProperty(RootBeanDefinition repositoryBeanDef, Element element) {
-		if(element != null) {
-			setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef, element, "saltSource",element.getAttribute(SALT_SOURCE_REF) );
-		} 
+		if (element != null) {
+			setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef, element, "saltSource", element
+					.getAttribute(SALT_SOURCE_REF));
+		}
 	}
-	
+
 	/**
 	 * 
 	 * @param repositoryBeanDef
 	 * @param element
 	 */
 	private void setPasswordEncoderProperty(RootBeanDefinition repositoryBeanDef, Element element) {
-		if(element != null) {
-			setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef, element, "passwordEncoder",element.getAttribute(PASSWORD_ENCODER_REF) );
-		} 
+		if (element != null) {
+			setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef, element, "passwordEncoder", element
+					.getAttribute(PASSWORD_ENCODER_REF));
+		}
 	}
+
 	/**
 	 * 
 	 * @param repositoryBeanDef
@@ -107,21 +111,22 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe
 	 * @param property
 	 * @param reference
 	 */
-	private void setBeanReferenceOrInnerBeanDefinitions(RootBeanDefinition repositoryBeanDef, Element element ,String property, String reference) {		
-			// check for encoderBeanRef attribute
-			if (StringUtils.hasLength(reference)) {
-				repositoryBeanDef.getPropertyValues().addPropertyValue(property, new RuntimeBeanReference(reference));
-			}
-			else {
-				doSetInnerBeanDefinitions(repositoryBeanDef, element,property);
-			}
+	private void setBeanReferenceOrInnerBeanDefinitions(RootBeanDefinition repositoryBeanDef, Element element,
+			String property, String reference) {
+		// check for encoderBeanRef attribute
+		if (StringUtils.hasLength(reference)) {
+			repositoryBeanDef.getPropertyValues().addPropertyValue(property, new RuntimeBeanReference(reference));
+		}
+		else {
+			doSetInnerBeanDefinitions(repositoryBeanDef, element, property);
+		}
 	}
 
 	/**
 	 * 
 	 * @param repositoryBeanDef
 	 * @param element
-	 * @param property 
+	 * @param property
 	 */
 	private void doSetInnerBeanDefinitions(RootBeanDefinition repositoryBeanDef, Element element, String property) {
 		NodeList children = element.getChildNodes();
@@ -142,12 +147,13 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe
 				}
 				if (PASSWORD_ENCODER.equals(node.getLocalName())) {
 					RootBeanDefinition passwordEncoderInnerBeanDefinition = createPasswordEncoder(childElement);
-					repositoryBeanDef.getPropertyValues().addPropertyValue(property, passwordEncoderInnerBeanDefinition);
+					repositoryBeanDef.getPropertyValues()
+							.addPropertyValue(property, passwordEncoderInnerBeanDefinition);
 				}
 			}
 		}
 	}
-	
+
 	/**
 	 * 
 	 * @param childElement
@@ -157,12 +163,12 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe
 		String attributeValue = childElement.getAttribute("method");
 		RootBeanDefinition definition = null;
 		// TODO: add other encoders support
-		if(attributeValue.equals("md5")){
-			 definition = new RootBeanDefinition(Md5PasswordEncoder.class);
+		if (attributeValue.equals("md5")) {
+			definition = new RootBeanDefinition(Md5PasswordEncoder.class);
 		}
 		return definition;
 	}
-	
+
 	/**
 	 * 
 	 * @param saltSourceTypeElement
@@ -170,22 +176,21 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe
 	 */
 	private RootBeanDefinition createReflectionSaltSource(Element saltSourceTypeElement) {
 		RootBeanDefinition definition = new RootBeanDefinition(ReflectionSaltSource.class);
-		definition.getPropertyValues().addPropertyValue("userPropertyToUse", saltSourceTypeElement.getAttribute("userPropertyToUse"));
+		definition.getPropertyValues().addPropertyValue("userPropertyToUse",
+				saltSourceTypeElement.getAttribute("userPropertyToUse"));
 		return definition;
 	}
-	
+
 	/**
 	 * 
 	 * @param saltSourceTypeElement
 	 * @return
 	 */
-	private RootBeanDefinition createSystemWideSaltSource( Element saltSourceTypeElement) {
+	private RootBeanDefinition createSystemWideSaltSource(Element saltSourceTypeElement) {
 		RootBeanDefinition definition = new RootBeanDefinition(SystemWideSaltSource.class);
-		definition.getPropertyValues().addPropertyValue("systemWideSalt", saltSourceTypeElement.getAttribute("systemWideSalt"));
+		definition.getPropertyValues().addPropertyValue("systemWideSalt",
+				saltSourceTypeElement.getAttribute("systemWideSalt"));
 		return definition;
 	}
 
-	
 }
-
-

+ 5 - 4
core/src/main/java/org/acegisecurity/config/RememberMeServicesBeanDefinitionParser.java

@@ -23,7 +23,7 @@ public class RememberMeServicesBeanDefinitionParser extends AbstractBeanDefiniti
 	
 	private static final String PRINCIPAL_REPOSITORY_BEAN_REF = "principalRepositoryBeanRef";
 	
-	private static final String USER_DETAILS_SERVICE = "userDetailsService";
+	private static final String USER_DETAILS_SERVICE_PROPERTY = "userDetailsService";
 	
 	/*
 	 * key is optional; if unspecified, pick a rnd int and use for all unspecified key properties for acegi beans
@@ -48,12 +48,13 @@ public class RememberMeServicesBeanDefinitionParser extends AbstractBeanDefiniti
 		//	 check if rememberMeServicesBeanRef is defined and if it's specified use its referred bean
 		String rememberMeServicesRef = element.getAttribute(PRINCIPAL_REPOSITORY_BEAN_REF);
 		if (StringUtils.hasLength(rememberMeServicesRef)) {
-			rememberMeServicesBeanDef.getPropertyValues().addPropertyValue(USER_DETAILS_SERVICE,
+			rememberMeServicesBeanDef.getPropertyValues().addPropertyValue(USER_DETAILS_SERVICE_PROPERTY,
 					new RuntimeBeanReference(rememberMeServicesRef));
 		}  
 		else {
-			// auto-detects everything
-			rememberMeServicesBeanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT);
+			// register a bean definition parse
+			RootBeanDefinition configurer = new RootBeanDefinition(RemeberMeServicesDependenciesConfigurer.class);
+			parserContext.getReaderContext().registerWithGeneratedName(configurer);
 		}
 		return rememberMeServicesBeanDef;
 	}

+ 20 - 10
core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd

@@ -125,16 +125,26 @@
 	</xsd:complexType>
 
 	<!-- Logout Filter -->
-	<xsd:element name="logout-support" type="LogoutFilter" />
-
-	<xsd:complexType name="LogoutFilter">
-		<!-- Write other attributes -->
-		<xsd:attribute name="id" type="xsd:ID" />
-		<xsd:attribute name="redirectAfterLogoutUrl" type="xsd:string"
-			default="/" />
-		<xsd:attribute name="logoutUrl" type="xsd:string"
-			default="/logout" />
-	</xsd:complexType>
+	<xsd:element name="logout-support">
+		<xsd:complexType>
+			<!-- Write other attributes -->
+			<xsd:attribute name="id" type="xsd:ID">
+				<xsd:annotation>
+					<xsd:documentation>
+						<![CDATA[
+	The unique identifier for a bean.
+				]]>
+					</xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="redirectAfterLogoutUrl"
+				type="xsd:string" default="/" />
+			<xsd:attribute name="logoutUrl" type="xsd:string"
+				default="/logout" />
+				<xsd:anyAttribute namespace="##other" processContents="lax"/>
+		</xsd:complexType>
+	</xsd:element>
+
 
 	<!-- Exception Translation Filter -->
 	<xsd:element name="exception-translation"

+ 78 - 73
core/src/test/java/org/acegisecurity/config/AuthenticationRepositoryParserTest.java

@@ -22,94 +22,99 @@ import org.springframework.util.Assert;
 
 /**
  * @author vpuri
- *
+ * 
  */
 public class AuthenticationRepositoryParserTest extends TestCase {
-	
+
 	public void testAuthenticationRepositoryDefaultWithAutoUserdetails() {
-		ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/authentication-dao-defaults.xml");
-		ConfigurableListableBeanFactory clbf = 
-			(ConfigurableListableBeanFactory)context.getAutowireCapableBeanFactory();
-		
+		ApplicationContext context = new ClassPathXmlApplicationContext(
+				"org/acegisecurity/config/authentication-dao-defaults.xml");
+		ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) context
+				.getAutowireCapableBeanFactory();
+
 		String[] names = clbf.getBeanNamesForType(AuthenticationProvider.class);
 		assertEquals(1, names.length);
-		
+
 		// check bean class
-		RootBeanDefinition definition = (RootBeanDefinition)clbf.getBeanDefinition(names[0]);
-	    assertEquals(DaoAuthenticationProvider.class, definition.getBeanClass());
-		
-		DaoAuthenticationProvider provider = (DaoAuthenticationProvider)context.getBean("authenticationRepository");
+		RootBeanDefinition definition = (RootBeanDefinition) clbf.getBeanDefinition(names[0]);
+		assertEquals(DaoAuthenticationProvider.class, definition.getBeanClass());
+
+		DaoAuthenticationProvider provider = (DaoAuthenticationProvider) context.getBean("authenticationRepository");
 		Assert.isAssignable(JdbcDaoImpl.class, provider.getUserDetailsService().getClass());
-		
+
 	}
-	
-	public void testCollaboratorsAsInnerBeans(){
-		ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/authentication-innerbeans.xml");
-		ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory)context.getAutowireCapableBeanFactory();
+
+	public void testCollaboratorsAsInnerBeans() {
+		ApplicationContext context = new ClassPathXmlApplicationContext(
+				"org/acegisecurity/config/authentication-innerbeans.xml");
+		ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) context
+				.getAutowireCapableBeanFactory();
 		// get the main bean definition, there should be only one
 		String[] names = clbf.getBeanNamesForType(AuthenticationProvider.class);
 		assertEquals(1, names.length);
-		RootBeanDefinition definition = (RootBeanDefinition)clbf.getBeanDefinition(names[0]);
-	    assertEquals(DaoAuthenticationProvider.class, definition.getBeanClass());
-	    
-	    
-	    // get the 2 inner beans
-	    PropertyValue saltSourceBean = definition.getPropertyValues().getPropertyValue("saltSource");
-	    assertEquals("saltSource", saltSourceBean.getName());
-	    
-	    //get the BeanDefinition	    
-	    RootBeanDefinition saltsourceDef = (RootBeanDefinition) saltSourceBean.getValue();
-	    Assert.isAssignable(SaltSource.class,saltsourceDef.getBeanClass());
-	    
-	    PropertyValue encoder = definition.getPropertyValues().getPropertyValue("passwordEncoder");
-	    assertEquals("passwordEncoder", encoder.getName());
-	    
-	    //get the BeanDefinition	    
-	    RootBeanDefinition encoderDef = (RootBeanDefinition) encoder.getValue();
-	    Assert.isAssignable(PasswordEncoder.class,encoderDef.getBeanClass());
-	    
-		assertEquals("incorrect bean class name", encoderDef.getBeanClassName(),Md5PasswordEncoder.class.getName());
+		RootBeanDefinition definition = (RootBeanDefinition) clbf.getBeanDefinition(names[0]);
+		assertEquals(DaoAuthenticationProvider.class, definition.getBeanClass());
+
+		// get the 2 inner beans
+		PropertyValue saltSourceBean = definition.getPropertyValues().getPropertyValue("saltSource");
+		assertEquals("saltSource", saltSourceBean.getName());
+
+		// get the BeanDefinition
+		RootBeanDefinition saltsourceDef = (RootBeanDefinition) saltSourceBean.getValue();
+		Assert.isAssignable(SaltSource.class, saltsourceDef.getBeanClass());
+
+		PropertyValue encoder = definition.getPropertyValues().getPropertyValue("passwordEncoder");
+		assertEquals("passwordEncoder", encoder.getName());
+
+		// get the BeanDefinition
+		RootBeanDefinition encoderDef = (RootBeanDefinition) encoder.getValue();
+		Assert.isAssignable(PasswordEncoder.class, encoderDef.getBeanClass());
+
+		assertEquals("incorrect bean class name", encoderDef.getBeanClassName(), Md5PasswordEncoder.class.getName());
 	}
-	
+
 	public void testCollaboratorsAsBeanRef() {
-		ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/authentication-beanRef-attributes.xml");
-		ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory)context.getAutowireCapableBeanFactory();
-		//		get the main bean definition, there should be only one
+		ApplicationContext context = new ClassPathXmlApplicationContext(
+				"org/acegisecurity/config/authentication-beanRef-attributes.xml");
+		ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) context
+				.getAutowireCapableBeanFactory();
+		// get the main bean definition, there should be only one
 		String[] names = clbf.getBeanNamesForType(AuthenticationProvider.class);
 		assertEquals(1, names.length);
-		RootBeanDefinition definition = (RootBeanDefinition)clbf.getBeanDefinition(names[0]);
-	    assertEquals(DaoAuthenticationProvider.class, definition.getBeanClass());
-	    
-	    // get the referred collaborators
-	    
-	    PropertyValue userDetailsBean = definition.getPropertyValues().getPropertyValue("userDetailsService");
-	    assertEquals("userDetailsService", userDetailsBean.getName());
-	    
-	    PropertyValue saltSourceBean = definition.getPropertyValues().getPropertyValue("saltSource");
-	    assertEquals("saltSource", saltSourceBean.getName());
-	    
-	    //get the BeanDefinition	    
-	    RuntimeBeanReference saltsourceDef = (RuntimeBeanReference) saltSourceBean.getValue();
-	    assertEquals("refToSaltSource",saltsourceDef.getBeanName());
-	    
-	    PropertyValue encoder = definition.getPropertyValues().getPropertyValue("passwordEncoder");
-	    assertEquals("passwordEncoder", encoder.getName());
-	    
-	    //get the BeanDefinition	    
-	    RuntimeBeanReference encoderDef = (RuntimeBeanReference) encoder.getValue();
-	    assertEquals("refToPasswordEncoder",encoderDef.getBeanName());
-	    
-	    DaoAuthenticationProvider provider = (DaoAuthenticationProvider)context.getBean("authenticationRepository");
-	    assertTrue(provider.getPasswordEncoder() instanceof PasswordEncoder);
-	    assertEquals(Md5PasswordEncoder.class, provider.getPasswordEncoder().getClass() );
+		RootBeanDefinition definition = (RootBeanDefinition) clbf.getBeanDefinition(names[0]);
+		assertEquals(DaoAuthenticationProvider.class, definition.getBeanClass());
+
+		// get the referred collaborators
+
+		PropertyValue userDetailsBean = definition.getPropertyValues().getPropertyValue("userDetailsService");
+		assertEquals("userDetailsService", userDetailsBean.getName());
+
+		PropertyValue saltSourceBean = definition.getPropertyValues().getPropertyValue("saltSource");
+		assertEquals("saltSource", saltSourceBean.getName());
+
+		// get the BeanDefinition
+		RuntimeBeanReference saltsourceDef = (RuntimeBeanReference) saltSourceBean.getValue();
+		assertEquals("refToSaltSource", saltsourceDef.getBeanName());
+
+		PropertyValue encoder = definition.getPropertyValues().getPropertyValue("passwordEncoder");
+		assertEquals("passwordEncoder", encoder.getName());
+
+		// get the BeanDefinition
+		RuntimeBeanReference encoderDef = (RuntimeBeanReference) encoder.getValue();
+		assertEquals("refToPasswordEncoder", encoderDef.getBeanName());
+
+		DaoAuthenticationProvider provider = (DaoAuthenticationProvider) context.getBean("authenticationRepository");
+		assertTrue(provider.getPasswordEncoder() instanceof PasswordEncoder);
+		assertEquals(Md5PasswordEncoder.class, provider.getPasswordEncoder().getClass());
 	}
-	
-	public void testAutodetectionOfUserDetailsService(){
-		ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/authentication-defaults.xml");
-		 DaoAuthenticationProvider provider = (DaoAuthenticationProvider)context.getBean("authenticationRepository");
-		 assertNotNull(provider.getUserDetailsService());
-		 assertNull(provider.getSaltSource());
-		 assertEquals(PlaintextPasswordEncoder.class, provider.getPasswordEncoder().getClass());
-		 
+
+	public void testAutodetectionOfUserDetailsService() {
+		ApplicationContext context = new ClassPathXmlApplicationContext(
+				"org/acegisecurity/config/authentication-defaults.xml");
+		DaoAuthenticationProvider provider = (DaoAuthenticationProvider) context.getBean("authenticationRepository");
+		assertNotNull(provider.getUserDetailsService());
+		assertNull(provider.getSaltSource());
+		assertEquals(PlaintextPasswordEncoder.class, provider.getPasswordEncoder().getClass());
+
 	}
 }

+ 4 - 3
core/src/test/resources/org/acegisecurity/config/logout-filter-with-handlers.xml

@@ -13,9 +13,10 @@ 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) -->
 	<!-- The logoutUrl and redirectAfterLogout are both optional and default to that shown -->
-	<security:logout-support id="logoutFilter"
-		redirectAfterLogoutUrl="/" logoutUrl="/logout" />
-
+	<security:logout-support id="logoutFilter" logoutUrl="/logout" redirectAfterLogoutUrl="/"/>
+	
+	
+	
 	<security:authentication-remember-me-services
 		id="rememberMeServices" key="someValue" />
 

+ 24 - 28
samples/pom.xml

@@ -1,29 +1,25 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.acegisecurity</groupId>
-    <artifactId>acegi-security-parent</artifactId>
-    <version>1.1-SNAPSHOT</version>
-  </parent>
-  <artifactId>acegi-security-samples</artifactId>
-  <name>Acegi Security System for Spring - Samples</name>
-  <packaging>pom</packaging>
-  <dependencies>
-    <dependency>
-      <groupId>org.acegisecurity</groupId>
-      <artifactId>acegi-security-tiger</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
-  <modules>
-    <module>annotations</module>
-    <module>attributes</module>
-    <module>contacts</module>
-    <module>contacts-tiger</module>
-  </modules>
-
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.acegisecurity</groupId>
+ <artifactId>acegi-security-samples</artifactId>
+ <packaging>pom</packaging>
+ <version>1.1-SNAPSHOT</version>
+ <name>acegi-security-samples</name>
+ <parent>
+   <groupId>org.acegisecurity</groupId>
+   <artifactId>acegi-security-parent</artifactId>
+   <version>1.1-SNAPSHOT</version>
+ </parent>
+ <modules>
+<!--
+   <module>acegifier</module>
+   <module>annotations</module>
+   <module>attributes</module>
+   <module>contacts</module>
+   <module>contacts-tiger</module>
+   <module>dms</module>
+-->
+   <module>tutorial</module>
+ </modules>
 </project>

+ 7 - 5
samples/tutorial/src/main/webapp/WEB-INF/applicationContext-acegi-security.xml

@@ -42,10 +42,11 @@
 
 	<!-- 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 -->
-	<security:logout-support id="logoutFilter" redirectAfterLogoutUrl="/index.jsp" logoutUrl="/j_acegi_logout"/>
+	<security:logout-support id="logoutFilter"
+		redirectAfterLogoutUrl="/index.jsp" logoutUrl="/j_acegi_logout" />
 
 	<security:authentication-remember-me-services
-		id="rememberMeServices" key="someValue" principalRepositoryBeanRef="userDetailsService"/>
+		id="rememberMeServices" key="someValue" />
 
 
 	<bean id="securityContextLogoutHandler"
@@ -60,8 +61,8 @@
 	<security:authentication-mechanism id="authenticationManager" />
 
 	<!-- dao authentication provider "authenticationRepository" -->
-	<security:authentication-repository id="daoAuthenticationProvider" repositoryBeanRef="userDetailsService"/>
-	
+	<security:authentication-repository id="daoAuthenticationProvider" />
+
 
 	<!-- UserDetailsService is the most commonly frequently Acegi Security interface implemented by end users -->
 	<security:principal-repository id="userDetailsService">
@@ -72,7 +73,8 @@
 		class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />
 
 	<!-- makes the filter, but does little else, as it auto-detects everything -->
-	<security:authentication-remember-me-filter id="rememberMeProcessingFilter" />
+	<security:authentication-remember-me-filter
+		id="rememberMeProcessingFilter" />
 
 	<bean id="anonymousProcessingFilter"
 		class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">