2
0
Эх сурвалжийг харах

SEC-271: Spring 2-based configuration simplification of Acegi Security

Vishal Puri 18 жил өмнө
parent
commit
566314dae5
19 өөрчлөгдсөн 1308 нэмэгдсэн , 6 устгасан
  1. 23 6
      core/pom.xml
  2. 190 0
      core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java
  3. 78 0
      core/src/main/java/org/acegisecurity/config/ContextIntegrationBeanDefinitionParser.java
  4. 49 0
      core/src/main/java/org/acegisecurity/config/RememberMeFilterBeanDefinitionParser.java
  5. 61 0
      core/src/main/java/org/acegisecurity/config/RememberMeServicesBeanDefinitionParser.java
  6. 28 0
      core/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java
  7. 1 0
      core/src/main/resources/META-INF/spring.handlers
  8. 2 0
      core/src/main/resources/META-INF/spring.schemas
  9. 221 0
      core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd
  10. 115 0
      core/src/test/java/org/acegisecurity/config/AuthenticationRepositoryParserTest.java
  11. 44 0
      core/src/test/java/org/acegisecurity/config/HttpSessionContextIntegrationParserTest.java
  12. 15 0
      core/src/test/java/org/acegisecurity/config/RememberMeBeanDefinitionParserTest.java
  13. 53 0
      core/src/test/resources/org/acegisecurity/config/authentication-beanRef-attributes.xml
  14. 60 0
      core/src/test/resources/org/acegisecurity/config/authentication-dao-defaults.xml
  15. 40 0
      core/src/test/resources/org/acegisecurity/config/authentication-defaults.xml
  16. 50 0
      core/src/test/resources/org/acegisecurity/config/authentication-innerbeans.xml
  17. 68 0
      core/src/test/resources/org/acegisecurity/config/remember-me-defaults.xml
  18. 147 0
      core/src/test/resources/org/acegisecurity/config/security-namespaces.xml
  19. 63 0
      core/src/test/resources/org/acegisecurity/config/session-context-integration-defaults.xml

+ 23 - 6
core/pom.xml

@@ -7,13 +7,14 @@
     <artifactId>acegi-security-parent</artifactId>
     <version>1.1-SNAPSHOT</version>
   </parent>
+  <packaging>jar</packaging>
   <artifactId>acegi-security</artifactId>
   <name>Acegi Security System for Spring</name>
 
   <scm>
-    <connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core</connection>
-    <developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core</developerConnection>
-    <url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core/</url>
+    <connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core</connection>
+    <developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core</developerConnection>
+    <url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core/</url>
   </scm>
 
   <dependencies>
@@ -36,9 +37,9 @@
       <optional>true</optional>
     </dependency>
     <dependency>
-      <groupId>ehcache</groupId>
+      <groupId>net.sf.ehcache</groupId>
       <artifactId>ehcache</artifactId>
-      <version>1.1</version>
+      <version>1.2.4</version>
       <optional>true</optional>
     </dependency>
     <dependency>
@@ -127,7 +128,7 @@
   </dependencies>
 
   <build>
-    <resources>
+    <resources><!--
       <resource>
         <directory>${basedir}/../</directory>
         <targetPath>META-INF</targetPath>
@@ -145,6 +146,22 @@
         <filtering>false</filtering>
       </resource>
       <resource>
+        <directory>${basedir}/src/main/resources/org/acegisecurity/config</directory>
+        <targetPath>META-INF</targetPath>
+        <includes>
+          <include>spring.handlers</include>
+        </includes>
+        <filtering>false</filtering>
+      </resource>
+      <resource>
+        <directory>${basedir}/src/main/resources/org/acegisecurity/config</directory>
+        <targetPath>META-INF</targetPath>
+        <includes>
+          <include>spring.schemas</include>
+        </includes>
+        <filtering>false</filtering>
+      </resource>
+      --><resource>
         <directory>${basedir}/src/main/resources</directory>
         <targetPath>/</targetPath>
         <includes>

+ 190 - 0
core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java

@@ -0,0 +1,190 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+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.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author vpuri
+ * 
+ */
+public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDefinitionParser   {
+
+	// ~~ Instance Variables
+
+	private static final String REPOSITORY_BEAN_REF = "repositoryBeanRef";
+
+	private static final String USER_DETAILS_SERVICE = "userDetailsService";
+
+	private static final String SALT_SOURCE_ELEMENT = "salt-source";
+
+	private static final String SALT_SOURCE_REF = "saltSourceBeanRef";
+
+	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";
+	
+	
+	
+	// ~~ Methods
+	/**
+	 * TODO: Document Me !!!
+	 */
+	public AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+		Assert.notNull(parserContext, "ParserContext must not be null");
+		
+		RootBeanDefinition repositoryBeanDef = new RootBeanDefinition(DaoAuthenticationProvider.class);
+		
+		// if repositoryBeanRef is specified use its referred bean
+		String userDetailsRef = element.getAttribute(REPOSITORY_BEAN_REF);
+		if (StringUtils.hasLength(userDetailsRef)) {
+			repositoryBeanDef.getPropertyValues().addPropertyValue(USER_DETAILS_SERVICE,
+					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);
+		}
+		//	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) );
+		} 
+	}
+	
+	/**
+	 * 
+	 * @param repositoryBeanDef
+	 * @param element
+	 */
+	private void setPasswordEncoderProperty(RootBeanDefinition repositoryBeanDef, Element element) {
+		if(element != null) {
+			setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef, element, "passwordEncoder",element.getAttribute(PASSWORD_ENCODER_REF) );
+		} 
+	}
+	/**
+	 * 
+	 * @param repositoryBeanDef
+	 * @param element
+	 * @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);
+			}
+	}
+
+	/**
+	 * 
+	 * @param repositoryBeanDef
+	 * @param element
+	 */
+	private void doSetInnerBeanDefinitions(RootBeanDefinition repositoryBeanDef, Element element) {
+		NodeList children = element.getChildNodes();
+		for (int i = 0, n = children.getLength(); i < n; i++) {
+			Node node = children.item(i);
+
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				Element childElement = (Element) node;
+				RootBeanDefinition innerBeanDefinition = null;
+
+				if (SYSTEM_WIDE_SALT_SOURCE.equals(node.getLocalName())) {
+					innerBeanDefinition = createSystemWideSaltSource(childElement);
+					repositoryBeanDef.getPropertyValues().addPropertyValue("saltSource", innerBeanDefinition);
+				}
+				else if (REFLECTION_SALT_SOURCE.equals(node.getLocalName())) {
+					innerBeanDefinition = createReflectionSaltSource(childElement);
+					repositoryBeanDef.getPropertyValues().addPropertyValue("saltSource", innerBeanDefinition);
+				}
+				if (PASSWORD_ENCODER.equals(node.getLocalName())) {
+					RootBeanDefinition passwordEncoderInnerBeanDefinition = createPasswordEncoder(childElement);
+					repositoryBeanDef.getPropertyValues().addPropertyValue("passwordEncoder", passwordEncoderInnerBeanDefinition);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * 
+	 * @param childElement
+	 * @return
+	 */
+	private RootBeanDefinition createPasswordEncoder(Element childElement) {
+		String attributeValue = childElement.getAttribute("method");
+		RootBeanDefinition definition = null;
+		// TODO: add other encoders support
+		if(attributeValue.equals("md5")){
+			 definition = new RootBeanDefinition(Md5PasswordEncoder.class);
+		}
+		return definition;
+	}
+	
+	/**
+	 * 
+	 * @param saltSourceTypeElement
+	 * @return
+	 */
+	private RootBeanDefinition createReflectionSaltSource(Element saltSourceTypeElement) {
+		RootBeanDefinition definition = new RootBeanDefinition(ReflectionSaltSource.class);
+		definition.getPropertyValues().addPropertyValue("userPropertyToUse", saltSourceTypeElement.getAttribute("userPropertyToUse"));
+		return definition;
+	}
+	
+	/**
+	 * 
+	 * @param saltSourceTypeElement
+	 * @return
+	 */
+	private RootBeanDefinition createSystemWideSaltSource( Element saltSourceTypeElement) {
+		RootBeanDefinition definition = new RootBeanDefinition(SystemWideSaltSource.class);
+		definition.getPropertyValues().addPropertyValue("systemWideSalt", saltSourceTypeElement.getAttribute("systemWideSalt"));
+		return definition;
+	}
+
+	
+}
+
+

+ 78 - 0
core/src/main/java/org/acegisecurity/config/ContextIntegrationBeanDefinitionParser.java

@@ -0,0 +1,78 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.context.HttpSessionContextIntegrationFilter;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.core.Conventions;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * 
+ * @author vpuri
+ * 
+ */
+public class ContextIntegrationBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
+	
+	private static final String HTTP_SESSION_CONTEXT_INTEGRATION = "session-context-integration";
+	
+	private static final String SESSION_CREATION = "sessionCreation";
+	
+	
+
+	private static final String IF_REQUIRED = "ifRequired";
+
+	private static final String ALWAYS = "always";
+
+	private static final String NEVER = "never";
+
+	
+	@Override
+	protected Class getBeanClass(Element element) {
+		return HttpSessionContextIntegrationFilter.class;
+	}
+	
+	
+	@Override
+	protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+		
+		NamedNodeMap attributes = element.getAttributes();
+		
+		for (int x = 0; x < attributes.getLength(); x++) {
+			Attr attribute = (Attr) attributes.item(x);
+			String attributeName = attribute.getLocalName();
+			if ( !ID_ATTRIBUTE.equals(attributeName)) {
+				if (attributeName.equals(SESSION_CREATION)) {
+					String sessionCreation = element.getAttribute(SESSION_CREATION);
+					
+					if(sessionCreation.equals(IF_REQUIRED)) {
+						builder.addPropertyValue("allowSessionCreation", Boolean.TRUE);
+					}
+					
+					if(sessionCreation.equals(ALWAYS)) {
+						builder.addPropertyValue("allowSessionCreation", Boolean.TRUE);
+					}
+					
+					if(sessionCreation.equals(NEVER)) {
+						builder.addPropertyValue("allowSessionCreation", Boolean.FALSE);
+					}
+				}
+				else{			
+					String propertyName = Conventions.attributeNameToPropertyName(attributeName);
+					Assert.state(StringUtils.hasText(propertyName),
+							"Illegal property name returned from 'extractPropertyName(String)': cannot be null or empty.");
+					builder.addPropertyValue(propertyName, attribute.getValue());			
+				}
+			}
+		}	
+	}
+}
+
+	

+ 49 - 0
core/src/main/java/org/acegisecurity/config/RememberMeFilterBeanDefinitionParser.java

@@ -0,0 +1,49 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.ui.rememberme.RememberMeProcessingFilter;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author vpuri
+ *
+ *@since
+ */
+public class RememberMeFilterBeanDefinitionParser extends AbstractBeanDefinitionParser implements
+		BeanDefinitionParser {
+
+	private static final String REMEMBER_ME_SERVICES_REF = "rememberMeServicesBeanRef";
+	
+	private static final String REMEMBER_ME_SERVICES = "rememberMeServices";
+
+	/**
+	 * 
+	 */
+	protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+		Assert.notNull(parserContext, "ParserContext must not be null");
+		
+		RootBeanDefinition rememberMeFilterBeanDef = new RootBeanDefinition(RememberMeProcessingFilter.class);
+		
+		// detect all the required dependencies and autowire them by type
+		rememberMeFilterBeanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT);
+		
+		// check if rememberMeServicesBeanRef is defined and if it's specified use its referred bean
+		String rememberMeServicesRef = element.getAttribute(REMEMBER_ME_SERVICES_REF);
+		if (StringUtils.hasLength(rememberMeServicesRef)) {
+			rememberMeFilterBeanDef.getPropertyValues().addPropertyValue(REMEMBER_ME_SERVICES,
+					new RuntimeBeanReference(rememberMeServicesRef));
+		} 
+		return rememberMeFilterBeanDef;
+	}
+
+}

+ 61 - 0
core/src/main/java/org/acegisecurity/config/RememberMeServicesBeanDefinitionParser.java

@@ -0,0 +1,61 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author vpuri
+ *
+ */
+public class RememberMeServicesBeanDefinitionParser extends AbstractBeanDefinitionParser implements
+		BeanDefinitionParser {
+	
+	private static final String PRINCIPAL_REPOSITORY_BEAN_REF = "principalRepositoryBeanRef";
+	
+	private static final String USER_DETAILS_SERVICE = "userDetailsService";
+	
+	/*
+	 * key is optional; if unspecified, pick a rnd int and use for all unspecified key properties for acegi beans
+	 */
+	private static final String KEY = "key";
+
+	/**
+	 * 
+	 */
+	protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+		Assert.notNull(parserContext, "ParserContext must not be null");		
+		
+		RootBeanDefinition rememberMeServicesBeanDef = new RootBeanDefinition(TokenBasedRememberMeServices.class);
+		
+		String keyValue = element.getAttribute(KEY);
+		if (StringUtils.hasLength(keyValue)) {
+			rememberMeServicesBeanDef.getPropertyValues().addPropertyValue(KEY,keyValue);
+		}  else {
+			// pick a rnd int
+		}
+		
+		//	 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,
+					new RuntimeBeanReference(rememberMeServicesRef));
+		}  
+		else {
+			// auto-detects everything
+			rememberMeServicesBeanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT);
+		}
+		return rememberMeServicesBeanDef;
+	}
+
+}

+ 28 - 0
core/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java

@@ -0,0 +1,28 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+/**
+ * {@link org.springframework.beans.factory.xml.NamespaceHandler} for the '<code>security</code>' namespace.
+ * @author vpuri
+ * 
+ * @since 
+ */
+public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
+
+	/**
+	 * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
+	 * '<code>context-integration</code>', ' and '<code></code>' elements.
+	 */
+	public void init() {
+		registerBeanDefinitionParser("session-context-integration", new ContextIntegrationBeanDefinitionParser());
+		registerBeanDefinitionParser("authentication-repository", new AuthenticationRepositoryBeanDefinitionParser());
+		registerBeanDefinitionParser("authentication-remember-me-services", new RememberMeServicesBeanDefinitionParser());
+		registerBeanDefinitionParser("authentication-remember-me-filter", new RememberMeFilterBeanDefinitionParser());
+	}
+
+}

+ 1 - 0
core/src/main/resources/META-INF/spring.handlers

@@ -0,0 +1 @@
+http\://www.springframework.org/schema/security=org.acegisecurity.config.SecurityNamespaceHandler

+ 2 - 0
core/src/main/resources/META-INF/spring.schemas

@@ -0,0 +1,2 @@
+http\://www.springframework.org/schema/security/spring-security-2.0.xsd=org/acegisecurity/config/spring-security-2.0.xsd
+

+ 221 - 0
core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd

@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+
+<xsd:schema xmlns="http://www.springframework.org/schema/security"
+	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://www.springframework.org/schema/security"
+	elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+
+
+	<xsd:element name="session-context-integration">
+		<xsd:complexType>
+			<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="sessionCreation"
+				default="ifRequired">
+				<xsd:annotation>
+					<xsd:documentation>
+						<![CDATA[
+	Indicates if this filter can create a HttpSession if
+	needed (sessions are always created sparingly, but setting this value to
+	false will prohibit sessions from ever being created).
+	Defaults to true. Do not set to false if
+	you have set forceEagerSessionCreation to true ,
+	as the properties would be in conflict.
+							]]>
+					</xsd:documentation>
+				</xsd:annotation>
+				<xsd:simpleType>
+					<xsd:restriction base="xsd:string">
+						<xsd:enumeration value="ifRequired" />
+						<xsd:enumeration value="never" />
+						<xsd:enumeration value="always" />
+					</xsd:restriction>
+				</xsd:simpleType>
+			</xsd:attribute>
+
+			<xsd:attribute name="forceEagerSessionCreation"
+				default="false" type="defaultable-boolean" use="optional">
+				<xsd:annotation>
+					<xsd:documentation>
+						<![CDATA[
+	Indicates if this filter is required to create a <code>HttpSession</code>
+	for every request before proceeding through the filter chain, even if the
+	<code>HttpSession</code> would not ordinarily have been created. By
+	default this is <code>false</code>, which is entirely appropriate for
+	most circumstances as you do not want a <code>HttpSession</code>
+	created unless the filter actually needs one. It is envisaged the main
+	situation in which this property would be set to <code>true</code> is
+	if using other filters that depend on a <code>HttpSession</code>
+	already existing, such as those which need to obtain a session ID. This
+	is only required in specialised cases, so leave it set to
+	<code>false</code> unless you have an actual requirement and are
+	conscious of the session creation overhead.
+							]]>
+					</xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="cloneFromHttpSession" default="false"
+				type="defaultable-boolean" use="optional">
+				<xsd:annotation>
+					<xsd:documentation>
+						<![CDATA[
+	Indicates whether the <code>SecurityContext</code> will be cloned from
+	the <code>HttpSession</code>. The default is to simply reference (ie
+    the default is <code>false</code>). The default may cause issues if
+ 	concurrent threads need to have a different security identity from other
+	threads being concurrently processed that share the same
+	<code>HttpSession</code>. In most normal environments this does not
+	represent an issue, as changes to the security identity in one thread is
+	allowed to affect the security identitiy in other threads associated with
+	the same <code>HttpSession</code>. For unusual cases where this is not
+	permitted, change this value to <code>true</code> and ensure the
+	{@link #context} is set to a <code>SecurityContext</code> that
+	implements {@link Cloneable} and overrides the <code>clone()</code>
+	method.
+							]]>
+					</xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:element name="authentication-remember-me-filter"
+		type="RememberMeFilter" />
+
+	<xsd:complexType name="RememberMeFilter">
+		<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="rememberMeServicesBeanRef" type="xsd:string"
+			use="optional" />
+	</xsd:complexType>
+	
+	<xsd:element name="authentication-remember-me-services"
+		type="RememberMeServices" />
+
+	<xsd:complexType name="RememberMeServices">
+		<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="key" type="xsd:string"
+			use="optional" />
+		<xsd:attribute name="principalRepositoryBeanRef" type="xsd:string"
+			use="optional" />
+	</xsd:complexType>
+
+
+
+
+	<xsd:element name="authentication-repository"
+		type="AuthenticationRepositoryType" />
+
+	<xsd:complexType name="AuthenticationRepositoryType">
+		<xsd:sequence>
+			<xsd:element name="salt-source" type="SaltSource"
+				minOccurs="0" maxOccurs="1" />
+			<xsd:element name="password-encoder" type="PasswordEncoder"
+				minOccurs="0" maxOccurs="1" />
+		</xsd:sequence>
+		<xsd:attributeGroup ref="AuthenticationRepositoryAttributes" />
+	</xsd:complexType>
+
+	<!-- <security:salt-source source="systemwide|reflection" salt="salt"/> -->
+	<xsd:complexType name="SaltSource">
+		<xsd:sequence>
+			<xsd:choice minOccurs="0" maxOccurs="1">
+				<xsd:element name="system-wide">
+					<xsd:complexType>
+						<xsd:attribute name="systemWideSalt"
+							type="xsd:string" />
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="reflection">
+					<xsd:complexType>
+						<xsd:attribute name="userPropertyToUse"
+							type="xsd:string" />
+					</xsd:complexType>
+				</xsd:element>
+			</xsd:choice>
+		</xsd:sequence>
+		<xsd:attribute name="saltSourceBeanRef" type="xsd:string"
+			use="optional" />
+	</xsd:complexType>
+
+	<xsd:complexType name="PasswordEncoder">
+		<xsd:sequence>
+			<xsd:choice minOccurs="0" maxOccurs="1">
+				<xsd:element name="encoder">
+					<xsd:complexType>
+						<xsd:attribute name="method" type="encoders" />
+					</xsd:complexType>
+				</xsd:element>
+			</xsd:choice>
+		</xsd:sequence>
+		<xsd:attribute name="encoderBeanRef" type="xsd:string"
+			use="optional" />
+	</xsd:complexType>
+
+	<xsd:attributeGroup name="AuthenticationRepositoryAttributes">
+		<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="repositoryBeanRef" type="xsd:string">
+			<xsd:annotation>
+				<xsd:documentation>
+					<![CDATA[
+	Reference of a bean.
+				]]>
+				</xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+	</xsd:attributeGroup>
+
+	<!-- simple internal types -->
+	<xsd:simpleType name="defaultable-boolean">
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="true" />
+			<xsd:enumeration value="false" />
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="encoders">
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="md5" />
+			<xsd:enumeration value="md5Hex" />
+			<xsd:enumeration value="sha" />
+			<xsd:enumeration value="shaHex" />
+			<xsd:enumeration value="custom" />
+		</xsd:restriction>
+	</xsd:simpleType>
+
+
+
+
+</xsd:schema>

+ 115 - 0
core/src/test/java/org/acegisecurity/config/AuthenticationRepositoryParserTest.java

@@ -0,0 +1,115 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.providers.AuthenticationProvider;
+import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
+import org.acegisecurity.providers.dao.SaltSource;
+import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
+import org.acegisecurity.providers.encoding.PasswordEncoder;
+import org.acegisecurity.providers.encoding.PlaintextPasswordEncoder;
+import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+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();
+		
+		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");
+		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();
+		// 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());
+	}
+	
+	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
+		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() );
+	}
+	
+	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());
+		 
+	}
+}

+ 44 - 0
core/src/test/java/org/acegisecurity/config/HttpSessionContextIntegrationParserTest.java

@@ -0,0 +1,44 @@
+/**
+ * 
+ */
+package org.acegisecurity.config;
+
+import javax.servlet.Filter;
+
+import org.acegisecurity.context.HttpSessionContextIntegrationFilter;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+import junit.framework.TestCase;
+
+/**
+ * @author vpuri
+ *
+ */
+public class HttpSessionContextIntegrationParserTest extends TestCase {
+	
+	public void testApplicationContext() {
+		ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/session-context-integration-defaults.xml");
+		ConfigurableListableBeanFactory clbf = 
+			(ConfigurableListableBeanFactory)context.getAutowireCapableBeanFactory();
+		
+		String[] names = clbf.getBeanNamesForType(Filter.class);
+		assertEquals(1, names.length);
+		
+		// check bean name
+		RootBeanDefinition definition = (RootBeanDefinition)clbf.getBeanDefinition(names[0]);
+		assertEquals(HttpSessionContextIntegrationFilter.class, definition.getBeanClass());
+		
+		// check properties
+		//get the bean
+		HttpSessionContextIntegrationFilter filter = (HttpSessionContextIntegrationFilter)context.getBean("httpSessionContextIntegrationFilter");
+		assertFalse(filter.isAllowSessionCreation());
+		assertNotNull(definition.getPropertyValues().getPropertyValue("allowSessionCreation"));
+		assertFalse(filter.isForceEagerSessionCreation());
+		assertFalse(filter.isCloneFromHttpSession());
+	}
+
+}

+ 15 - 0
core/src/test/java/org/acegisecurity/config/RememberMeBeanDefinitionParserTest.java

@@ -0,0 +1,15 @@
+package org.acegisecurity.config;
+
+import junit.framework.TestCase;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class RememberMeBeanDefinitionParserTest extends TestCase {
+	
+	public void testRememberMeDefaults() {
+		ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/remember-me-defaults.xml");
+		
+	}
+
+}

+ 53 - 0
core/src/test/resources/org/acegisecurity/config/authentication-beanRef-attributes.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+	http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<security:authentication-repository id="authenticationRepository" repositoryBeanRef="refToUserDetailsService">
+		<security:salt-source saltSourceBeanRef="refToSaltSource"/>
+		<security:password-encoder encoderBeanRef="refToPasswordEncoder"/>		
+	</security:authentication-repository>
+
+	<bean id="refToUserDetailsService"
+		class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
+		<property name="dataSource">
+			<ref bean="dataSource" />
+		</property>
+	</bean>
+
+	<bean id="dataSource"
+		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+		<property name="driverClassName">
+			<value>org.hsqldb.jdbcDriver</value>
+		</property>
+		<property name="url">
+			<value>jdbc:hsqldb:mem:test</value>
+			<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
+		</property>
+		<property name="username">
+			<value>sa</value>
+		</property>
+		<property name="password">
+			<value></value>
+		</property>
+	</bean>
+	
+	<bean id="refToSaltSource"
+		class="org.acegisecurity.providers.dao.salt.SystemWideSaltSource">
+		<property name="systemWideSalt">
+			<value>12345</value>
+		</property>
+	</bean>
+
+	<bean id="refToPasswordEncoder"
+		class="org.acegisecurity.providers.encoding.Md5PasswordEncoder" />
+	
+</beans>

+ 60 - 0
core/src/test/resources/org/acegisecurity/config/authentication-dao-defaults.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<!-- Case 1: defaults (userDetailsService mandatory)-->
+	<!--  autocreate userDetailsService with dataSource(search in ctx) injected -->
+
+	<security:authentication-repository id="authenticationRepository">
+		<!--<security:salt-source>
+			<security:system-wide systemWideSalt="12345" />
+		</security:salt-source>
+		--><security:password-encoder encoderBeanRef="passwordEncoder"/>
+		<!-- OR <security:password-encoder>
+				<security:encoder method="md5"/>
+		</security:password-encoder>
+	--></security:authentication-repository>
+
+	<bean id="userDetailsService"
+		class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
+		<property name="dataSource">
+			<ref bean="dataSource" />
+		</property>
+	</bean>
+
+	<bean id="dataSource"
+		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+		<property name="driverClassName">
+			<value>org.hsqldb.jdbcDriver</value>
+		</property>
+		<property name="url">
+			<value>jdbc:hsqldb:mem:test</value>
+			<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
+		</property>
+		<property name="username">
+			<value>sa</value>
+		</property>
+		<property name="password">
+			<value></value>
+		</property>
+	</bean>
+
+	<bean id="saltSource"
+		class="org.acegisecurity.providers.dao.salt.SystemWideSaltSource">
+		<property name="systemWideSalt">
+			<value>12345</value>
+		</property>
+	</bean>
+
+	<bean id="passwordEncoder"
+		class="org.acegisecurity.providers.encoding.Md5PasswordEncoder" />
+</beans>

+ 40 - 0
core/src/test/resources/org/acegisecurity/config/authentication-defaults.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+	http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<security:authentication-repository id="authenticationRepository"/>
+
+	<bean id="userDetailsService"
+		class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
+		<property name="dataSource">
+			<ref bean="dataSource" />
+		</property>
+	</bean>
+
+	<bean id="dataSource"
+		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+		<property name="driverClassName">
+			<value>org.hsqldb.jdbcDriver</value>
+		</property>
+		<property name="url">
+			<value>jdbc:hsqldb:mem:test</value>
+			<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
+		</property>
+		<property name="username">
+			<value>sa</value>
+		</property>
+		<property name="password">
+			<value></value>
+		</property>
+	</bean>
+	
+</beans>

+ 50 - 0
core/src/test/resources/org/acegisecurity/config/authentication-innerbeans.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<!-- Case 1: defaults (userDetailsService mandatory)-->
+	<!--  autocreate userDetailsService with dataSource(search in ctx) injected -->
+
+	<security:authentication-repository id="authenticationRepository">
+		<security:salt-source>
+			<security:system-wide systemWideSalt="12345" />
+		</security:salt-source>
+		<security:password-encoder>
+			<security:encoder method="md5" />
+		</security:password-encoder>
+	</security:authentication-repository>
+
+	<bean id="AnyBeanIdAsThisBeanWillBeAutoDetectedAndInjectedInauthenticationRepositoryUsingAutoWireByType"
+		class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
+		<property name="dataSource">
+			<ref bean="dataSource" />
+		</property>
+	</bean>
+
+	<bean id="dataSource"
+		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+		<property name="driverClassName">
+			<value>org.hsqldb.jdbcDriver</value>
+		</property>
+		<property name="url">
+			<value>jdbc:hsqldb:mem:test</value>
+			<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
+		</property>
+		<property name="username">
+			<value>sa</value>
+		</property>
+		<property name="password">
+			<value></value>
+		</property>
+	</bean>
+	
+</beans>

+ 68 - 0
core/src/test/resources/org/acegisecurity/config/remember-me-defaults.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<!-- ======================== AUTHENTICATION ======================= -->
+
+	<!-- makes the filter, but does little else, as it auto-detects everything -->
+	<security:authentication-remember-me-filter id="rememberMeFilter"
+		rememberMeServicesBeanRef="rememberMeServices" />
+
+	<!-- services should auto-detect UserDetails from app ctx if principalRepository was not specified; -->
+	<!-- key is optional; if unspecified, in the NamespaceHandler pick a rnd int and use for all unspecified key properties for acegi beans -->
+	<security:authentication-remember-me-services
+		id="rememberMeServices" key="someValue"
+		principalRepositoryBeanRef="userDetailsService" />
+
+	<!-- The rules are:
+		AuthenticationManager interface is implemented by ProviderManager
+		So if you have any auto-detection, create a ProviderManager definition
+		If ProviderManager.setProvider(List) is never called, auto-detect all AuthenticationProviders from app ctx, using Ordered to resolve their order
+		Every authentication mechanism OR provider must start with security:authentication-something
+		Use appropriate attrs and elements depending on provider or mechanism
+	-->
+	<bean id="authenticationManager"
+		class="org.acegisecurity.providers.ProviderManager">
+		<property name="providers">
+			<list>
+				<ref local="authenticationRepository" />
+			</list>
+		</property>
+	</bean>
+
+
+	<security:authentication-repository id="authenticationRepository" />
+
+	<bean id="userDetailsService"
+		class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
+		<property name="dataSource">
+			<ref bean="dataSource" />
+		</property>
+	</bean>
+
+	<bean id="dataSource"
+		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+		<property name="driverClassName">
+			<value>org.hsqldb.jdbcDriver</value>
+		</property>
+		<property name="url">
+			<value>jdbc:hsqldb:mem:test</value>
+			<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
+		</property>
+		<property name="username">
+			<value>sa</value>
+		</property>
+		<property name="password">
+			<value></value>
+		</property>
+	</bean>
+</beans>

+ 147 - 0
core/src/test/resources/org/acegisecurity/config/security-namespaces.xml

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+	http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<!-- introspect all bean definitions for an explicit object of a "required" type, and if not found, add it. You can turn OFF ones you dont want added via attributes -->
+	<security:security-autoconfig exceptionTranslation="disable" sessionContextIntegration="disable" logoutSupport="disable" filterChain="disable"  servletRequestEmulation="disabled" anonyomousRoleGranter="disabled"/>
+
+	<!-- autodetect attribute is the default, and an exception is thrown if false, as the expectation is they will write their own legacy <beans> format
+	FilterChainProxy bean definition is dissatisfied with the auto approach. The auto approach simply creates a bean definition similar to that shown
+	below with the AUTODETECT_ALL_ORDERED_FILTERs. As suggested, this causes a runtime check of app ctx for all javax.servlet.Filter instances, and
+	for each that also implemented Ordered, these are automatically applied to the pattern shown (which is **/* in the case of autodetect=true).*-->
+	<security:filter-chain id="id" />
+	<bean id="dcdc" class="FilterChainProxy">
+		<property name="chainConfig">
+			<value>
+				**/*=AUTODETECT_ALL_ORDERED_FILTERS
+				**/*=filter1,filter2,filter3
+			</value>
+		</property>
+	</bean>
+	<!--  also provide an OrderedFilterAdapter, impls Filter and Ordered, and can be configured declaratively in Spring XML (eg SiteMesh), setOrder, setDelegate(Filter object) -->
+
+	<!-- creates a bean definition for an AccessDecisionManager; strategy defaults to AffirmativeBased; 
+	superclass AbstractAccessDecisionManager requires refactoring so if no setProvider(List) given, it introspects app ctx for all AccessDecisionVoters
+	and uses their Ordered interface to apply them; if one doesn't implement Ordered, assume it is Integer.MAX_VALUE -->
+	<security:authorization-manager id="id" strategy="consensus|unanimous|affirmative"/>
+
+	<!-- ======================== AUTHENTICATION ======================= -->
+
+	<!-- sessionCreation defaults to ifRequired. -->
+	<security:session-context-integration id="httpSessionContextIntegrationFilter" sessionCreation="never|ifRequired|always" />
+
+	<!-- The rules are:
+	     AuthenticationManager interface is implemented by ProviderManager
+	     So if you have any auto-detection, create a ProviderManager definition
+	     If ProviderManager.setProvider(List) is never called, auto-detect all AuthenticationProviders from app ctx, using Ordered to resolve their order
+	     Every authentication mechanism OR provider must start with security:authentication-something
+	     Use appropriate attrs and elements depending on provider or mechanism
+	      -->
+	<security:authentication-repository id="id" repositoryBeanRef="beanIdOfRepositoryIfUnspecifiedAutoDetectTheirUserDetailsInstance">
+		<security:salt-source saltSourceBeanRef="beanRefOfAnExternalEncoder"/> <!--  or allow it to be written inline as an inner bean -->
+		<security:password-encoder encoder="md5|md5Hex|sha|shaHex|custom" encoderBeanRef="beanRefOfAnExternalEncoder"/> <!-- same story here, inner beans allowed -->
+	</security:authentication-repository>
+	
+	<security:salt-source>
+			<security:system-wide systemWideSalt="12345"/>
+			<security-reflection userPropertyToUse="sss"/>
+	</security:salt-source>
+	
+	
+	<!--  the URLs are all mandatory and have no defaults (well, except authenticationUrl) -->
+	<security:authentication-form id="id" authenticationUrl="/login" loginFormUrl="/login.html" errorFormUrl="error.html"/>
+	
+	<!-- AuthenticationEntryPoints handled across the system via Ordered interface; every Acegi entry point has an order; the highest order wins and
+	is used as the entry point by ExceptionTranslationFilter; for things like BasicAuthenticationfilter, they're smart enough to know they need a
+	BasicAuthenticationProcessingFilterEntryPoint, so they use that one; here we have an entryPointOrder to say when we make the BasicEntryPoint,
+	we will call setOrder(2) such that this app effectively will use somehing with a higher order as the app-wide default -->
+	<security:authentication-basic id="id" realmName="Spring Security Application" entryPointOrder="2"/>
+	
+	<!-- This is used if they want an out-of-the-bx UserDetails; if they write their own, this goes away and they wire a legacy bean definition and then the various
+	beans depending on a UserDetails will auto-detect it at runtime OR provide a way of setUserDetails(UserDetails) if to specified explicitly.
+	If they fail to provide a repository, the security-autodetect will set one up for them with a few basic in-memory users and pwds -->
+	<security:principal-repository id="id">
+		<security:ldap x="you can do the attributes and suitable nested elements"/>
+		<security:jdbc x="you can do the attributes and suitable nested elements"/>
+		<security:properties resource="resourceStringToPropertiesFile"> <!-- if they specify a resource attrib, that means throw exception if they nest some user-definition data) -->
+			<security:user-definition username="ben" password="nottellingYou" enabled="true" it="more stuff if you want">
+				<security:granted-authority authority="ROLE_ANONYMOUS"/>
+				<ref bean="fooBarAuthority"/>
+			</security:user-definition>
+		</security:properties>
+	</security:principal-repository>
+
+	<!-- makes the filter, but does little else, as it auto-detects everything -->
+	<security:authentication-remember-me-filter id="id" rememberMeServicesBeanRef="theId" />
+
+	<!-- services should auto-detect UserDetails from app ctx if principalRepository was not specified; key is handled in same way as discussed earlier -->
+	<security:authentication-remember-me-services id="id" key="someValue" principalRepositoryBeanRef="jdbcDaoImpl" />
+
+	<!-- key is optional; if unspecified, in the NamespaceHandler pick a rnd int and use for all unspecified key properties for acegi beans -->
+	<security:anonymous-role-granter " id="id" key="someValue" >
+		<security:granted-authority authority="ROLE_ANONYMOUS"/>
+		<ref bean="fooBarAuthority"/>
+	</security:anonymous-role-granter>	
+
+	<security:granted-authority id="fooBarAuthority" authority="ROLE_FOOBAR"/>
+
+	<!-- 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"/>
+
+
+	<!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->
+
+	<!--  channel security out of scope; they use existing bean definition format; the channel filter will auto-detect and use Ordered interface as discussed above -->
+	
+	<!--  any kind of ACL support is out of scope; frankly it is too hard for 1.1.0 -->
+
+	<!-- ensure element name is not overlapping with portlet or spring web flow or tapestry URI patterns, as this filter is incompatible with them -->
+	<security:authorization-http-url>
+		<security:url-mapping source="xml - the default and no other options" sourceBeanId="referenceToTheirObjectDefinitionSource">
+			<!-- Specify security:uri-patterns in order of processing; each pattern must specify EITHER a regularExpression OR a path, but not both
+				 and ALL patterns in the url-mapping MUST be of the SAME type (ie cannot mix a regular expression and Ant Path) - give exception if tried -->
+			<security:uri-pattern path ="/index.jsp" regularExpression="whatever">
+				<security:configuration-attribute attribute="ROLE_A"/>
+				<ref bean="someExternalConfigurationAttributeThatIsATopLevelBean"/>
+			</security:uri-pattern>
+			<security:uri-pattern path ="/**" regularExperssion="whatever">
+				<security:configuration-attribute attribute="ROLE_A"/>
+				<ref bean="someExternalConfigurationAttributeThatIsATopLevelBean"/>
+			</security:uri-pattern>
+		</security:url-mapping>
+	</security:authorization-http-url>
+
+	<!-- the source refers to use of the relevant concete ObjectDefinitionSource; user can alternately specify their own instance and refer to it
+	via the sourceBeanId property; in that case they must specify "custom"; if unspecified, it means it's described as nested elements using the
+	security:method-pattern element, and you will therefore create it via the MethodDefinitionSourceEditor (that is what the default source=xml means, too)
+	For aspectj and springAop, that means create a MethodSecurityInterceptor and AspectJSecurityInterceptor bean definition respectively (in the case of
+	springAop, also create a MethodDefinitionSourceAdvisor); defaults to springAop=true, aspectJ=false -->
+	<security:authorization-joinpoint aspectj="false|true" springAop="true|false" >
+		<security:url-mapping source="custom|xml|attributes|annotations" sourceBeanId="referenceToTheirObjectDefinitionSource">
+			<security:method-pattern type="com.foo.Bar.whateverMethodNamePattern">
+				<security:configuration-attribute attribute="ROLE_A"/>
+				<ref bean="someExternalConfigurationAttributeThatIsATopLevelBean"/>
+			</security:method-pattern>
+		</security:url-mapping>
+		<!-- if get time, do a new security:pointcut-pattern -->
+	</security:authorization-joinpoint>
+
+	
+	<!-- Basically accessDeniedUrl is optional, we if unspecified impl will auto-detect any AccessDeniedHandler in ctx and use it; 
+	alternately if there are > 1 such handlers, we can nominate the one to use via accessDeniedBeanRef; provide nested elements for
+	other props; i do not mind if you move the access denied stuff to a sub-element -->
+	<security:exception-translation id="id" accessDeniedUrl="/accessDenied.jsp" accessDeniedBeanRef="theBeanToUse">
+		<security:entry-point path="/acegilogin.jsp" https="boolean"/>
+	</security:exception-translation>
+
+</beans>

+ 63 - 0
core/src/test/resources/org/acegisecurity/config/session-context-integration-defaults.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:security="http://www.springframework.org/schema/security"
+	xmlns:util="http://www.springframework.org/schema/util"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
+	http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
+	http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
+
+	<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
+	<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
+
+	<!-- ======================== AUTHENTICATION ======================= -->
+
+	<!-- sessionCreation defaults to ifRequired(true) always(true) never(false) . -->
+	<security:session-context-integration id="httpSessionContextIntegrationFilter" sessionCreation="never"	/>
+
+	<!-- The rules are:
+		AuthenticationManager interface is implemented by ProviderManager
+		So if you have any auto-detection, create a ProviderManager definition
+		If ProviderManager.setProvider(List) is never called, auto-detect all AuthenticationProviders from app ctx, using Ordered to resolve their order
+		Every authentication mechanism OR provider must start with security:authentication-something
+		Use appropriate attrs and elements depending on provider or mechanism
+	-->
+	
+	
+	<!-- Case 1 	
+	<security:authentication-repository id="id" repositoryBeanRef="userDetails">
+		<security:salt-source
+			saltSourceBeanRef="beanRefOfAnExternalEncoder" />
+		  or allow it to be written inline as an inner bean 
+		<security:password-encoder
+			encoder="md5|md5Hex|sha|shaHex|custom"
+			encoderBeanRef="beanRefOfAnExternalEncoder" />
+		 same story here, inner beans allowed 
+	</security:authentication-repository>
+	
+	<bean id="userDetails" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
+      <property name="dataSource"><ref bean="dataSource"/></property>
+    </bean>
+    
+     Case 2: autodetect userDetails
+    <security:authentication-repository id="id">
+		<security:salt-source
+			saltSourceBeanRef="beanRefOfAnExternalEncoder" />
+		  or allow it to be written inline as an inner bean 
+		<security:password-encoder
+			encoder="md5|md5Hex|sha|shaHex|custom"
+			encoderBeanRef="beanRefOfAnExternalEncoder" />
+		 same story here, inner beans allowed 
+	</security:authentication-repository>
+	
+	 Case 3: inner beans 
+	<security:authentication-repository id="id"
+		ref="userDetails">
+		<security:salt-source propertyName="propertyValue" />
+		  or allow it to be written inline as an inner bean 
+		<security:password-encoder encoder="md5" />
+		 same story here, inner beans allowed 
+	</security:authentication-repository>
+--></beans>
+