diff --git a/sandbox/spring-security-config/.classpath b/sandbox/spring-security-config/.classpath
new file mode 100644
index 0000000000..181f4e9f62
--- /dev/null
+++ b/sandbox/spring-security-config/.classpath
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/.project b/sandbox/spring-security-config/.project
new file mode 100644
index 0000000000..35276f865c
--- /dev/null
+++ b/sandbox/spring-security-config/.project
@@ -0,0 +1,21 @@
+
+ spring-security-config
+ Acegi Security System for Spring
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jem.workbench.JavaEMFNature
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/.settings/.component b/sandbox/spring-security-config/.settings/.component
new file mode 100644
index 0000000000..ab11e108c0
--- /dev/null
+++ b/sandbox/spring-security-config/.settings/.component
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/.settings/org.eclipse.jdt.core.prefs b/sandbox/spring-security-config/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..9fed997141
--- /dev/null
+++ b/sandbox/spring-security-config/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+#Fri May 25 12:12:42 EST 2007
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/sandbox/spring-security-config/.settings/org.eclipse.wst.common.project.facet.core.xml b/sandbox/spring-security-config/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000000..9bbcbd78eb
--- /dev/null
+++ b/sandbox/spring-security-config/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/basicauth/BasicProcessingFilter.java b/sandbox/spring-security-config/basicauth/BasicProcessingFilter.java
new file mode 100644
index 0000000000..6a226d53ed
--- /dev/null
+++ b/sandbox/spring-security-config/basicauth/BasicProcessingFilter.java
@@ -0,0 +1,239 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.ui.basicauth;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.acegisecurity.Authentication;
+import org.acegisecurity.AuthenticationException;
+import org.acegisecurity.AuthenticationManager;
+import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import org.acegisecurity.ui.AuthenticationDetailsSource;
+import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
+import org.acegisecurity.ui.rememberme.RememberMeServices;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.Ordered;
+import org.springframework.util.Assert;
+
+
+/**
+ * Processes a HTTP request's BASIC authorization headers, putting the result into the
+ * SecurityContextHolder.
For a detailed background on what this filter is designed to process,
+ * refer to RFC 1945, Section 11.1. Any realm name presented in
+ * the HTTP request is ignored.
+ * In summary, this filter is responsible for processing any request that has a HTTP request header of
+ * Authorization with an authentication scheme of Basic and a Base64-encoded
+ * username:password token. For example, to authenticate user "Aladdin" with password "open sesame" the
+ * following header would be presented:
+ * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==.
+ * This filter can be used to provide BASIC authentication services to both remoting protocol clients (such as
+ * Hessian and SOAP) as well as standard user agents (such as Internet Explorer and Netscape).
+ * If authentication is successful, the resulting {@link Authentication} object will be placed into the
+ * SecurityContextHolder.
+ * If authentication fails and ignoreFailure is false (the default), an {@link
+ * AuthenticationEntryPoint} implementation is called. Usually this should be {@link BasicProcessingFilterEntryPoint},
+ * which will prompt the user to authenticate again via BASIC authentication.
+ * Basic authentication is an attractive protocol because it is simple and widely deployed. However, it still
+ * transmits a password in clear text and as such is undesirable in many situations. Digest authentication is also
+ * provided by Acegi Security and should be used instead of Basic authentication wherever possible. See {@link
+ * org.acegisecurity.ui.digestauth.DigestProcessingFilter}.
+ * Note that if a {@link #rememberMeServices} is set, this filter will automatically send back remember-me
+ * details to the client. Therefore, subsequent requests will not need to present a BASIC authentication header as
+ * they will be authenticated using the remember-me mechanism.
+ * Do not use this class directly. Instead configure web.xml to use the {@link
+ * org.acegisecurity.util.FilterToBeanProxy}.
+ *
+ * @author Ben Alex
+ * @version $Id: BasicProcessingFilter.java 1783 2007-02-23 19:21:44Z luke_t $
+ */
+public class BasicProcessingFilter implements Filter, InitializingBean, Ordered {
+ //~ Static fields/initializers =====================================================================================
+
+ private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
+
+ //~ Instance fields ================================================================================================
+
+ private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
+ private AuthenticationEntryPoint authenticationEntryPoint;
+ private AuthenticationManager authenticationManager;
+ private RememberMeServices rememberMeServices;
+ private boolean ignoreFailure = false;
+ private int order;
+
+ //~ Methods ========================================================================================================
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(this.authenticationManager, "An AuthenticationManager is required");
+ Assert.notNull(this.authenticationEntryPoint, "An AuthenticationEntryPoint is required");
+ }
+
+ public void destroy() {}
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+
+ if (!(request instanceof HttpServletRequest)) {
+ throw new ServletException("Can only process HttpServletRequest");
+ }
+
+ if (!(response instanceof HttpServletResponse)) {
+ throw new ServletException("Can only process HttpServletResponse");
+ }
+
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+ String header = httpRequest.getHeader("Authorization");
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authorization header: " + header);
+ }
+
+ if ((header != null) && header.startsWith("Basic ")) {
+ String base64Token = header.substring(6);
+ String token = new String(Base64.decodeBase64(base64Token.getBytes()));
+
+ String username = "";
+ String password = "";
+ int delim = token.indexOf(":");
+
+ if (delim != -1) {
+ username = token.substring(0, delim);
+ password = token.substring(delim + 1);
+ }
+
+ if (authenticationIsRequired(username)) {
+ UsernamePasswordAuthenticationToken authRequest =
+ new UsernamePasswordAuthenticationToken(username, password);
+ authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
+
+ Authentication authResult;
+
+ try {
+ authResult = authenticationManager.authenticate(authRequest);
+ } catch (AuthenticationException failed) {
+ // Authentication failed
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
+ }
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+
+ if (rememberMeServices != null) {
+ rememberMeServices.loginFail(httpRequest, httpResponse);
+ }
+
+ if (ignoreFailure) {
+ chain.doFilter(request, response);
+ } else {
+ authenticationEntryPoint.commence(request, response, failed);
+ }
+
+ return;
+ }
+
+ // Authentication success
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authentication success: " + authResult.toString());
+ }
+
+ SecurityContextHolder.getContext().setAuthentication(authResult);
+
+ if (rememberMeServices != null) {
+ rememberMeServices.loginSuccess(httpRequest, httpResponse, authResult);
+ }
+ }
+ }
+
+ chain.doFilter(request, response);
+ }
+
+ private boolean authenticationIsRequired(String username) {
+ // Only reauthenticate if username doesn't match SecurityContextHolder and user isn't authenticated
+ // (see SEC-53)
+ Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
+
+ if(existingAuth == null || !existingAuth.isAuthenticated()) {
+ return true;
+ }
+
+ // Limit username comparison to providers which use usernames (ie UsernamePasswordAuthenticationToken)
+ // (see SEC-348)
+
+ if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public AuthenticationEntryPoint getAuthenticationEntryPoint() {
+ return authenticationEntryPoint;
+ }
+
+ public AuthenticationManager getAuthenticationManager() {
+ return authenticationManager;
+ }
+
+ public void init(FilterConfig arg0) throws ServletException {}
+
+ public boolean isIgnoreFailure() {
+ return ignoreFailure;
+ }
+
+ public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
+ Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
+ this.authenticationDetailsSource = authenticationDetailsSource;
+ }
+
+ public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
+ this.authenticationEntryPoint = authenticationEntryPoint;
+ }
+
+ public void setAuthenticationManager(AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+
+ public void setIgnoreFailure(boolean ignoreFailure) {
+ this.ignoreFailure = ignoreFailure;
+ }
+
+ public void setRememberMeServices(RememberMeServices rememberMeServices) {
+ this.rememberMeServices = rememberMeServices;
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+}
diff --git a/sandbox/spring-security-config/basicauth/BasicProcessingFilterEntryPoint.java b/sandbox/spring-security-config/basicauth/BasicProcessingFilterEntryPoint.java
new file mode 100644
index 0000000000..83f14c5fb3
--- /dev/null
+++ b/sandbox/spring-security-config/basicauth/BasicProcessingFilterEntryPoint.java
@@ -0,0 +1,89 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.ui.basicauth;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.acegisecurity.AuthenticationException;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
+import org.acegisecurity.util.OrderedUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+import org.springframework.util.Assert;
+
+
+/**
+ * Used by the SecurityEnforcementFilter to commence authentication via the {@link
+ * BasicProcessingFilter}.Once a user agent is authenticated using BASIC authentication, logout requires that
+ * the browser be closed or an unauthorized (401) header be sent. The simplest way of achieving the latter is to call
+ * the {@link #commence(ServletRequest, ServletResponse, AuthenticationException)} method below. This will indicate to
+ * the browser its credentials are no longer authorized, causing it to prompt the user to login again.
+ *
+ * @author Ben Alex
+ * @version $Id: BasicProcessingFilterEntryPoint.java 1822 2007-05-17 12:20:16Z vishalpuri $
+ */
+public class BasicProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean, Ordered, ApplicationContextAware {
+ //~ Instance fields ================================================================================================
+
+ private static final int DEFAULT_ORDER = Integer.MAX_VALUE;
+ private String realmName;
+ private int order = DEFAULT_ORDER;
+ private ApplicationContext applicationContext;
+
+ //~ Methods ========================================================================================================
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.hasText(realmName, "realmName must be specified");
+ if (order == DEFAULT_ORDER) {
+ OrderedUtils.copyOrderFromOtherClass(BasicProcessingFilter.class, applicationContext, this, true);
+ }
+ }
+
+ public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException)
+ throws IOException, ServletException {
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\"");
+ httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
+ }
+
+ public String getRealmName() {
+ return realmName;
+ }
+
+ public void setRealmName(String realmName) {
+ this.realmName = realmName;
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+}
diff --git a/sandbox/spring-security-config/basicauth/package.html b/sandbox/spring-security-config/basicauth/package.html
new file mode 100644
index 0000000000..dcd7c31c91
--- /dev/null
+++ b/sandbox/spring-security-config/basicauth/package.html
@@ -0,0 +1,5 @@
+
+
+Authenticates HTTP BASIC authentication requests.
+
+
diff --git a/sandbox/spring-security-config/pom.xml b/sandbox/spring-security-config/pom.xml
new file mode 100644
index 0000000000..96b37d72c8
--- /dev/null
+++ b/sandbox/spring-security-config/pom.xml
@@ -0,0 +1,122 @@
+
+
+ acegi-security-sandbox
+ org.acegisecurity
+ 1.0.4-SNAPSHOT
+
+ 4.0.0
+ org.acegisecurity
+ spring-security-config
+ spring-security-config
+ 1.0-SNAPSHOT
+ http://maven.apache.org
+
+
+ org.springframework
+ spring-remoting
+
+
+ org.springframework
+ spring-jdbc
+
+
+ org.springframework
+ spring-support
+ runtime
+
+
+ org.springframework
+ spring-mock
+ true
+
+
+ net.sf.ehcache
+ ehcache
+ 1.2.4
+ true
+
+
+ cas
+ casclient
+ 2.0.11
+ true
+
+
+ commons-lang
+ commons-lang
+ 2.1
+
+
+ commons-logging
+ commons-logging
+ 1.0.4
+
+
+ commons-codec
+ commons-codec
+ 1.3
+
+
+ oro
+ oro
+ 2.0.8
+
+
+ commons-collections
+ commons-collections
+ 3.1
+
+
+ aspectj
+ aspectjrt
+ 1.2
+ true
+
+
+ javax.servlet
+ jsp-api
+ 2.0
+ true
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ true
+
+
+ taglibs
+ standard
+ 1.0.6
+ true
+
+
+ hsqldb
+ hsqldb
+ 1.8.0.4
+ test
+
+
+ org.apache.directory.server
+ apacheds-core
+ 1.0.0
+ test
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.0.1
+ test
+
+
+ jmock
+ jmock
+ 1.0.1
+ test
+
+
+ log4j
+ log4j
+
+
+
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/App.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/App.java
new file mode 100644
index 0000000000..5feccae6ff
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/App.java
@@ -0,0 +1,13 @@
+package org.acegisecurity;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AccessDeniedHandlerBeanDefinitionLocator.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AccessDeniedHandlerBeanDefinitionLocator.java
new file mode 100644
index 0000000000..d3daa70e90
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AccessDeniedHandlerBeanDefinitionLocator.java
@@ -0,0 +1,50 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.acegisecurity.ui.AccessDeniedHandler;
+import org.acegisecurity.ui.ExceptionTranslationFilter;
+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.RootBeanDefinition;
+import org.springframework.util.Assert;
+
+/**
+ * @author vpuri
+ *
+ */
+public class AccessDeniedHandlerBeanDefinitionLocator implements BeanFactoryPostProcessor {
+
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+
+ Map m = beanFactory.getBeansOfType(AccessDeniedHandler.class);
+
+ List l = new ArrayList(m.values());
+
+
+
+ if (m.size() > 1) {
+ throw new IllegalArgumentException(
+ "More than one AccessDeniedHandler beans detected please refer to the one using "
+ + " [ accessDeniedBeanRef ] " + "attribute");
+ }
+ else if (m.size() == 1) {
+ // use this
+ String[] names = beanFactory.getBeanNamesForType(ExceptionTranslationFilter.class);
+ Assert.notEmpty(names, "No bean of type ExceptionTranslationFilter found in ApplicationContext");
+ RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[0]);
+ Assert.isAssignable(AccessDeniedHandler.class, l.get(0).getClass());
+ definition.getPropertyValues().addPropertyValue("accessDeniedHandler", l.get(0));
+ }
+ else {
+ // use the default one for now
+ }
+
+ }
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java
new file mode 100644
index 0000000000..77855a5ec4
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java
@@ -0,0 +1,80 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.acegisecurity.config;
+import org.acegisecurity.providers.ProviderManager;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.ManagedList;
+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;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * * {@link BeanDefinitionParser} for the authentication-mechanism tag,
+ * resolves to {@link org.acegisecurity.providers.ProviderManager}
+
+ * @author vpuri
+ * @see {@link org.springframework.beans.factory.BeanFactory}
+ * @see {@link org.acegisecurity.providers.ProviderManager}
+ *
+ */
+public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDefinitionParser implements
+ BeanDefinitionParser {
+ // ~ Instance fields
+ // ================================================================================================
+
+ private static final String AUTHENTICATION_JDBC = "authentication-jdbc";
+
+ private static final String REF = "ref";
+
+ // ~ Methods
+ // ========================================================================================================
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+
+ ManagedList providers = new ManagedList();
+ Assert.notNull(parserContext, "ParserContext must not be null");
+ RootBeanDefinition authMechanismBeanDef = new RootBeanDefinition(ProviderManager.class);
+ NodeList childNodes = element.getChildNodes();
+
+ for (int i = 0, n = childNodes.getLength(); i < n; i++) {
+ Node node = childNodes.item(i);
+
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element childElement = (Element) node;
+ //this.providerExists = true;
+
+ if (AUTHENTICATION_JDBC.equals(node.getLocalName())) {
+ String attribute = childElement.getAttribute(REF);
+ if (StringUtils.hasLength(attribute)) {
+ // create a beandefinition
+ providers.add(new RuntimeBeanReference(attribute));
+ }
+
+ }
+ // TODO:Add other providers here
+ }
+ authMechanismBeanDef.getPropertyValues().addPropertyValue("providers", providers);
+
+ }
+ return authMechanismBeanDef;
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProcessingFilterBeanDefinitionParser.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProcessingFilterBeanDefinitionParser.java
new file mode 100644
index 0000000000..c6ce35ac26
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProcessingFilterBeanDefinitionParser.java
@@ -0,0 +1,58 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
+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.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author vpuri
+ *
+ */
+public class AuthenticationProcessingFilterBeanDefinitionParser extends AbstractBeanDefinitionParser implements
+ BeanDefinitionParser {
+
+ // ~ Instance fields
+ // ================================================================================================
+
+ private static final String AUTHENTICATION_URL = "authenticationUrl";
+
+ private static final String ERROR_FORM_URL = "errorFormUrl";
+
+ private static final String DEFAULT_TARGET_URL = "defaultTargetUrl";
+
+ // ~ Methods
+ // ================================================================================================
+
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+
+ RootBeanDefinition definition = new RootBeanDefinition(AuthenticationProcessingFilter.class);
+
+ setPropertyIfAvailable(element, AUTHENTICATION_URL, "filterProcessesUrl", definition);
+ setPropertyIfAvailable(element, ERROR_FORM_URL, "authenticationFailureUrl", definition);
+ setPropertyIfAvailable(element, DEFAULT_TARGET_URL, "defaultTargetUrl", definition);
+
+ // register BFPP to re-unite all other collaborators
+ RootBeanDefinition postProcessor = new RootBeanDefinition(
+ AuthenticationProcessingFilterDependenciesConfigurer.class);
+ parserContext.getReaderContext().registerWithGeneratedName(postProcessor);
+
+ return definition;
+ }
+
+ private void setPropertyIfAvailable(Element element, String attribute, String property,
+ RootBeanDefinition definition) {
+ String propertyValue = element.getAttribute(attribute);
+ if (StringUtils.hasText(propertyValue)) {
+ definition.getPropertyValues().addPropertyValue(property, propertyValue);
+ }
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProcessingFilterDependenciesConfigurer.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProcessingFilterDependenciesConfigurer.java
new file mode 100644
index 0000000000..e134f41870
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProcessingFilterDependenciesConfigurer.java
@@ -0,0 +1,43 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.AuthenticationManager;
+import org.acegisecurity.ui.rememberme.RememberMeServices;
+import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
+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.RootBeanDefinition;
+
+/**
+ * @author vpuri
+ *
+ */
+public class AuthenticationProcessingFilterDependenciesConfigurer implements BeanFactoryPostProcessor {
+
+ // ~ Methods
+ // ================================================================================================
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+
+ String [] authenticationProcessingFilter = beanFactory.getBeanNamesForType(AuthenticationProcessingFilter.class);
+
+ RootBeanDefinition def = (RootBeanDefinition)beanFactory.getBeanDefinition(authenticationProcessingFilter[0]);
+
+ String[] remServiceNames = beanFactory.getBeanNamesForType(RememberMeServices.class);
+
+ RootBeanDefinition rememberMeServices = (RootBeanDefinition) beanFactory.getBeanDefinition(remServiceNames[0]);
+
+ if (remServiceNames.length > 0)
+ def.getPropertyValues()
+ .addPropertyValue("rememberMeServices", rememberMeServices);
+
+ String[] authManager = beanFactory.getBeanNamesForType(AuthenticationManager.class);
+
+ RootBeanDefinition authenticationManager = (RootBeanDefinition) beanFactory.getBeanDefinition(authManager[0]);
+
+ if (authManager.length > 0)
+ def.getPropertyValues().addPropertyValue("authenticationManager", authenticationManager);
+ }
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProviderOrderResolver.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProviderOrderResolver.java
new file mode 100644
index 0000000000..635f863a8c
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/AuthenticationProviderOrderResolver.java
@@ -0,0 +1,43 @@
+package org.acegisecurity.config;
+
+import java.util.Collections;
+
+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;
+
+public class AuthenticationProviderOrderResolver implements BeanFactoryPostProcessor {
+
+ /**
+ *
+ */
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ // retrieve all the AuthenticationProvider instances
+ ManagedList providers = retrieveAllAuthenticationProviders(beanFactory);
+ String[] names = beanFactory.getBeanNamesForType(AuthenticationManager.class);
+ RootBeanDefinition definition = (RootBeanDefinition)beanFactory.getBeanDefinition(names[0]);
+ definition.getPropertyValues().addPropertyValue("providers",providers);
+ }
+ /**
+ *
+ * @param beanFactory
+ * @return
+ */
+ private ManagedList retrieveAllAuthenticationProviders(ConfigurableListableBeanFactory beanFactory) {
+ String[] m = beanFactory.getBeanNamesForType(AuthenticationProvider.class);
+ ManagedList l = new ManagedList();
+ for(int i=0;i 1 such handlers, we can nominate the one to use via
+ * accessDeniedBeanRef;
+ *
+ * @author vpuri
+ * @since
+ */
+public class ExceptionTranslationFilterBeanDefinitionParser extends AbstractBeanDefinitionParser {
+
+ private static final String ACCESS_DENIED = "access-denied";
+
+ private static final String ACCESS_DENIED_REF = "accessDeniedBeanRef";
+
+ private static final String ACCESS_DENIED_URL = "accessDeniedUrl";
+
+ private static final String ENTRY_POINT = "entry-point";
+
+ private static final String ENTRY_POINT_REF ="entryPointBeanRef";
+
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+
+ RootBeanDefinition exceptionFilterDef = new RootBeanDefinition(ExceptionTranslationFilter.class);
+
+ // add handler
+ Element accessDeniedElement = DomUtils.getChildElementByTagName(element, ACCESS_DENIED);
+ setAccessDeniedHandlerProperty(parserContext, exceptionFilterDef, accessDeniedElement);
+
+ Element entryPointElement = DomUtils.getChildElementByTagName(element, ENTRY_POINT);
+ setEntryPointProperty(exceptionFilterDef, entryPointElement);
+
+ return exceptionFilterDef;
+ }
+
+ private void setEntryPointProperty(RootBeanDefinition exceptionFilterDef, Element entryPointElement) {
+ if (entryPointElement != null) {
+ setBeanReferenceOrInnerBeanDefinitions(exceptionFilterDef, entryPointElement, "authenticationEntryPoint",
+ entryPointElement.getAttribute(ENTRY_POINT_REF));
+ }
+ }
+
+ /**
+ *
+ * @param parserContext
+ * @param repositoryBeanDef
+ * @param element
+ */
+ private void setAccessDeniedHandlerProperty(ParserContext parserContext, RootBeanDefinition exceptionFilterDef,
+ Element accessDeniedElement) {
+ if (accessDeniedElement != null) {
+ setBeanReferenceOrInnerBeanDefinitions(exceptionFilterDef, accessDeniedElement, "accessDeniedHandler",
+ accessDeniedElement.getAttribute(ACCESS_DENIED_REF));
+ }
+ else {
+ // register BFPP to check if handler exist in application context,
+ // if > 1 throw error saying ref should be specified as there are
+ // more than one
+ RootBeanDefinition accessDeniedHandlerLocatorBeanDef = new RootBeanDefinition(
+ AccessDeniedHandlerBeanDefinitionLocator.class);
+ parserContext.getReaderContext().registerWithGeneratedName(accessDeniedHandlerLocatorBeanDef);
+ }
+ }
+
+ /**
+ *
+ * @param repositoryBeanDef
+ * @param element
+ * @param property
+ * @param reference
+ */
+ private void setBeanReferenceOrInnerBeanDefinitions(RootBeanDefinition exceptionFilterDef,
+ Element element, String property, String beanRef) {
+ // check for encoderBeanRef attribute
+ if (StringUtils.hasLength(beanRef)) {
+ exceptionFilterDef.getPropertyValues().addPropertyValue(property,
+ new RuntimeBeanReference(beanRef));
+ }
+ else {
+ doSetInnerBeanDefinitions(exceptionFilterDef, element, property);
+ }
+ }
+
+ /**
+ *
+ * @param repositoryBeanDef
+ * @param element
+ * @param property
+ */
+ private void doSetInnerBeanDefinitions(RootBeanDefinition exceptionFilterDef, Element accessDeniedElement,
+ String property) {
+ RootBeanDefinition accessDeniedHandlerBeanDef = new RootBeanDefinition(AccessDeniedHandlerImpl.class);
+ setPropertyIfAvailable(accessDeniedElement, ACCESS_DENIED_URL, "errorPage", accessDeniedHandlerBeanDef);
+ exceptionFilterDef.getPropertyValues().addPropertyValue(property, accessDeniedHandlerBeanDef);
+
+ }
+
+ private void setPropertyIfAvailable(Element element, String attribute, String property,
+ RootBeanDefinition definition) {
+ String propertyValue = element.getAttribute(attribute);
+ if (StringUtils.hasText(propertyValue)) {
+ definition.getPropertyValues().addPropertyValue(property, propertyValue);
+ }
+ }
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/LogoutFilterBeanDefinitionParser.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/LogoutFilterBeanDefinitionParser.java
new file mode 100644
index 0000000000..9c81a1bd82
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/LogoutFilterBeanDefinitionParser.java
@@ -0,0 +1,64 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.ui.logout.LogoutFilter;
+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.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author vpuri
+ * @since
+ */
+public class LogoutFilterBeanDefinitionParser extends AbstractBeanDefinitionParser {
+
+ // ~ Instance fields
+ // ================================================================================================
+ private static final String REDIRECT_AFTER_LOGOUT_URL = "redirectAfterLogoutUrl";
+
+ private static final String LOGOUT_URL = "logoutUrl";
+
+ // ~ Methods
+ // ================================================================================================
+
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+
+ // add the properties
+ RootBeanDefinition definition = new RootBeanDefinition(LogoutFilter.class);
+ setConstructorArgumentIfAvailable(0, element, REDIRECT_AFTER_LOGOUT_URL, "logoutSuccessUrl", definition);
+
+ setPropertyIfAvailable(element, LOGOUT_URL, "filterProcessesUrl", definition);
+
+ // register BFPP to check if LogoutFilter does not have setHandlers
+ // populated, introspect app ctx for LogoutHandlers, using Ordered (if
+ // present, otherwise assume Integer.MAX_VALUE)
+ RootBeanDefinition bfpp = new RootBeanDefinition(LogoutHandlerOrderResolver.class);
+ parserContext.getReaderContext().registerWithGeneratedName(bfpp);
+
+ return definition;
+ }
+
+ private void setConstructorArgumentIfAvailable(int index, Element element, String attribute, String property,
+ RootBeanDefinition definition) {
+ String propertyValue = element.getAttribute(attribute);
+ if (StringUtils.hasText(propertyValue)) {
+ definition.getConstructorArgumentValues().addIndexedArgumentValue(index, propertyValue);
+ }
+ }
+
+ private void setPropertyIfAvailable(Element element, String attribute, String property,
+ RootBeanDefinition definition) {
+ String propertyValue = element.getAttribute(attribute);
+ if (StringUtils.hasText(propertyValue)) {
+ definition.getPropertyValues().addPropertyValue(property, propertyValue);
+ }
+ }
+
+ //
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/LogoutHandlerOrderResolver.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/LogoutHandlerOrderResolver.java
new file mode 100644
index 0000000000..baa3c06a3a
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/LogoutHandlerOrderResolver.java
@@ -0,0 +1,95 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.acegisecurity.ui.logout.LogoutFilter;
+import org.acegisecurity.ui.logout.LogoutHandler;
+import org.acegisecurity.ui.logout.SecurityContextLogoutHandler;
+import org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.core.OrderComparator;
+import org.springframework.core.Ordered;
+
+/**
+ * @author vpuri
+ * @since
+ */
+public class LogoutHandlerOrderResolver implements BeanFactoryPostProcessor {
+
+ // ~ Methods
+ // ================================================================================================
+
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ // If LogoutFilter does not have setHandlers populated, introspect app
+ // ctx for LogoutHandlers, using Ordered (if present, otherwise assume
+ // Integer.MAX_VALUE)
+ String[] names = beanFactory.getBeanNamesForType(LogoutFilter.class);
+ RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[0]);
+ ValueHolder holder = getHandlersIfConfigured(beanFactory, definition);
+ if (holder == null) {
+ // intropect the appcontext for registerd LogoutHandler
+ List logoutHandlers = retrieveAllLogoutHandlers(beanFactory);
+ definition.getConstructorArgumentValues().addIndexedArgumentValue(1, logoutHandlers);
+ }
+ }
+
+ /**
+ *
+ * @param beanFactory
+ * @param definition
+ * @return
+ */
+ private ValueHolder getHandlersIfConfigured(ConfigurableListableBeanFactory beanFactory,
+ RootBeanDefinition definition) {
+ // there should be only one LogoutFilter
+ return definition.getConstructorArgumentValues().getArgumentValue(1, null);
+
+ }
+
+ /**
+ *
+ * @param beanFactory
+ * @return
+ */
+ private List retrieveAllLogoutHandlers(ConfigurableListableBeanFactory beanFactory) {
+ String[] names = beanFactory.getBeanNamesForType(LogoutHandler.class);
+ ManagedList list = new ManagedList();
+
+ for (int i = 0, n = names.length; i < n; i++) {
+ RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[i]);
+
+ if (definition.hasBeanClass()) {
+ if (Ordered.class.isAssignableFrom(definition.getBeanClass())) {
+ definition.getPropertyValues().addPropertyValue("order",
+ new Integer(getOrder(definition.getBeanClass())));
+ }
+ else {
+ definition.getPropertyValues().addPropertyValue("order", new Integer(Integer.MAX_VALUE));
+ }
+ }
+ list.add(definition);
+ }
+ Collections.sort(list, new OrderComparator());
+ return list;
+ }
+
+ private int getOrder(Class clazz) {
+ if (clazz.getName().equals(TokenBasedRememberMeServices.class.getName())) {
+ return 100;
+ }
+ if (clazz.getName().equals(SecurityContextLogoutHandler.class.getName())) {
+ return 200;
+ }
+ return Integer.MAX_VALUE;
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java
new file mode 100644
index 0000000000..581c95f74f
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java
@@ -0,0 +1,235 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import java.util.Properties;
+
+import org.acegisecurity.GrantedAuthorityImpl;
+import org.acegisecurity.userdetails.User;
+import org.acegisecurity.userdetails.UserDetails;
+import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl;
+import org.acegisecurity.userdetails.memory.InMemoryDaoImpl;
+import org.acegisecurity.userdetails.memory.UserAttribute;
+import org.acegisecurity.userdetails.memory.UserMap;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.config.PropertiesFactoryBean;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+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.StringUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author vpuri
+ *
+ */
+public class PrincipalRepositoryBeanDefinitionParser extends AbstractBeanDefinitionParser implements
+ BeanDefinitionParser {
+
+ // ~ Static fields/initializers =====================================================================================
+
+ private static final Log logger = LogFactory.getLog(PrincipalRepositoryBeanDefinitionParser.class);
+
+ // ~ Instance fields
+ // ================================================================================================
+ private static final String JDBC = "jdbc";
+
+ private static final String DATASOURCE_REF = "dataSourceBeanRef";
+
+ private static final String DATASOURCE = "dataSource";
+
+ private static final String JDBCTEMPLATE_REF = "jdbcTemplateBeanRef";
+
+ private static final String JDBCTEMPLATE = "jdbcTemplate";
+
+ private static final String AUTHORITIES_BY_USERNAME_QUERY = "authoritiesByUsernameQuery";
+
+ private static final String ROLE_PREFIX = "rolePrefix";
+
+ private static final String USERNAME_BASED_PRIMARY_KEY = "usernameBasedPrimaryKey";
+
+ private static final String PROPERTIES = "properties";
+
+ private static final String RESOURCE = "resource";
+
+ private static final String USER_PROPERTIES = "userProperties";
+
+ private static final String USER_DEFINITION = "user-definition";
+
+ private static final Object GRANTED_AUTHORITY = "granted-authority";
+
+ private static final String USERNAME = "username";
+
+ private static final String PASSWORD = "password";
+
+ private static final String ENABLED = "enabled";
+
+ private static final String GRANTED_AUTHORITY_REF = "granted-authority-ref";
+
+ private static final String AUTHORITY = "authority";
+
+ private static final String AUTHORITY_BEAN_REF="authorityBeanRef";
+
+ // ~ Method
+ // ================================================================================================
+ /**
+ *
+ */
+
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+ NodeList userDetailsServiceChildren = element.getChildNodes();
+ RootBeanDefinition userDetailsServiceDefinition = null;
+ for (int i = 0, n = userDetailsServiceChildren.getLength(); i < n; i++) {
+ Node userDetailsService = userDetailsServiceChildren.item(i);
+
+ if (JDBC.equals(userDetailsService.getLocalName()) && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
+ Element ele = (Element) userDetailsService;
+ userDetailsServiceDefinition = parseUserDetailsServiceJdbcDefinition(ele);
+ userDetailsServiceDefinition.setSource(parserContext.extractSource(element));
+ parserContext.getReaderContext().registerWithGeneratedName(userDetailsServiceDefinition);
+ }
+ if (PROPERTIES.equals(userDetailsService.getLocalName())
+ && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
+ Element ele = (Element) userDetailsService;
+
+ userDetailsServiceDefinition = new RootBeanDefinition(InMemoryDaoImpl.class);
+ userDetailsServiceDefinition.getPropertyValues().addPropertyValue(USER_PROPERTIES,
+ new RuntimeBeanReference(createPropertiesBeanDefinition(ele, parserContext)));
+ userDetailsServiceDefinition.setSource(parserContext.extractSource(element));
+ parserContext.getReaderContext().registerWithGeneratedName(userDetailsServiceDefinition);
+ }
+ if (USER_DEFINITION.equals(userDetailsService.getLocalName())
+ && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
+ Element ele = (Element) userDetailsService;
+
+ // create a UserMap which interns uses UserMapEditor
+ userDetailsServiceDefinition = createUserDefinition(ele, parserContext);
+ }
+ }
+ return userDetailsServiceDefinition;
+ }
+
+ private RootBeanDefinition createUserDefinition(Element ele, ParserContext parserContext) {
+ RootBeanDefinition definition = new RootBeanDefinition(InMemoryDaoImpl.class);
+
+ UserAttribute userAttribute = new UserAttribute();
+ UserMap userMap = new UserMap();
+
+ setPassword(ele, userAttribute);
+ setEnabled(ele, userAttribute);
+ setAuthorities(ele, userAttribute);
+
+ UserDetails user = new User(ele.getAttribute(USERNAME), userAttribute.getPassword(), userAttribute.isEnabled(),
+ true, true, true, userAttribute.getAuthorities());
+ userMap.addUser(user);
+ definition.getPropertyValues().addPropertyValue("userMap", userMap);
+ return definition;
+
+ }
+
+ private String createPropertiesBeanDefinition(Element ele, ParserContext parserContext) {
+ // properties element
+ RootBeanDefinition defintion = new RootBeanDefinition(PropertiesFactoryBean.class);
+ String propertyValue = ele.getAttribute(RESOURCE);
+ defintion.getPropertyValues().addPropertyValue("location", propertyValue);
+ defintion.setSource(parserContext.extractSource(ele));
+ return parserContext.getReaderContext().registerWithGeneratedName(defintion);
+ }
+
+ /**
+ *
+ * @param elementToParse
+ * @return
+ */
+ private RootBeanDefinition parseUserDetailsServiceJdbcDefinition(Element elementToParse) {
+ // parse attributes
+ RootBeanDefinition definition = new RootBeanDefinition(JdbcDaoImpl.class);
+ setPropertyIfAvailable(elementToParse, DATASOURCE_REF, DATASOURCE, definition);
+ setPropertyIfAvailable(elementToParse, JDBCTEMPLATE_REF, JDBCTEMPLATE, definition);
+ setPropertyIfAvailable(elementToParse, AUTHORITIES_BY_USERNAME_QUERY, AUTHORITIES_BY_USERNAME_QUERY, definition);
+ setPropertyIfAvailable(elementToParse, ROLE_PREFIX, ROLE_PREFIX, definition);
+ setPropertyIfAvailable(elementToParse, USERNAME_BASED_PRIMARY_KEY, USERNAME_BASED_PRIMARY_KEY, definition);
+ return definition;
+ }
+
+ protected void doParseProperties(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ Properties parsedProps = parserContext.getDelegate().parsePropsElement(element);
+ builder.addPropertyValue(PROPERTIES, parsedProps);
+ }
+
+ /**
+ *
+ * @param element
+ * @param attribute
+ * @param property
+ * @param definition
+ */
+ private void setPropertyIfAvailable(Element element, String attribute, String property,
+ RootBeanDefinition definition) {
+ String propertyValue = element.getAttribute(attribute);
+ if (StringUtils.hasText(propertyValue)) {
+ if (propertyValue.equals(DATASOURCE_REF) || propertyValue.equals(JDBCTEMPLATE_REF)) {
+ definition.getPropertyValues().addPropertyValue(property, new RuntimeBeanReference(propertyValue));
+ }
+ else {
+ definition.getPropertyValues().addPropertyValue(property, propertyValue);
+ }
+ }
+ }
+
+ private void setPassword(Element element, UserAttribute userAttribute) {
+ String propertyValue = element.getAttribute(PASSWORD);
+ if (StringUtils.hasText(propertyValue)) {
+ userAttribute.setPassword(propertyValue);
+ }
+ }
+
+ private void setEnabled(Element element, UserAttribute userAttribute) {
+ String propertyValue = element.getAttribute(ENABLED);
+ if (StringUtils.hasText(propertyValue)) {
+ if (propertyValue.equals("true")) {
+ userAttribute.setEnabled(true);
+ }
+ else {
+ userAttribute.setEnabled(false);
+ }
+ }
+ }
+
+ private void setAuthorities(Element ele, UserAttribute userAttribute) {
+ // get authorities
+ NodeList childNodes = ele.getChildNodes();
+
+ ManagedList authorities = new ManagedList();
+
+ for (int i = 0, n = childNodes.getLength(); i < n; i++) {
+ Node authorityNode = childNodes.item(i);
+
+ if (GRANTED_AUTHORITY.equals(authorityNode.getLocalName())
+ && authorityNode.getNodeType() == Element.ELEMENT_NODE) {
+ Element propertyValue = (Element) authorityNode;
+ authorities.add(new GrantedAuthorityImpl(propertyValue.getAttribute(AUTHORITY)));
+ }
+
+ if (GRANTED_AUTHORITY_REF.equals(authorityNode.getLocalName())
+ && authorityNode.getNodeType() == Element.ELEMENT_NODE) {
+ Element propertyValue = (Element) authorityNode;
+ String attribute = propertyValue.getAttribute(AUTHORITY_BEAN_REF);
+ if (StringUtils.hasLength(attribute)) {
+ authorities.add(new RuntimeBeanReference(attribute));
+ }
+ }
+ }
+ userAttribute.setAuthorities(authorities);
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RemeberMeServicesDependenciesConfigurer.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RemeberMeServicesDependenciesConfigurer.java
new file mode 100644
index 0000000000..24f1b68b8e
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RemeberMeServicesDependenciesConfigurer.java
@@ -0,0 +1,35 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.ui.rememberme.RememberMeServices;
+import org.acegisecurity.userdetails.UserDetailsService;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+
+/**
+ * @author vpuri
+ *
+ */
+public class RemeberMeServicesDependenciesConfigurer implements BeanFactoryPostProcessor {
+
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+
+ String [] userDetailServices = beanFactory.getBeanNamesForType(UserDetailsService.class);
+
+ String [] rememberMeService = beanFactory.getBeanNamesForType(RememberMeServices.class);
+
+ RootBeanDefinition definition=(RootBeanDefinition) beanFactory.getBeanDefinition(rememberMeService[0]);
+
+ // there should be only one principal-repository defined, pick the first one
+ if(userDetailServices.length!=0) {
+ definition.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(userDetailServices[0]));
+ }
+
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RememberMeFilterBeanDefinitionParser.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RememberMeFilterBeanDefinitionParser.java
new file mode 100644
index 0000000000..0d56d8aa2e
--- /dev/null
+++ b/sandbox/spring-security-config/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.ParserContext;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author vpuri
+ *
+ *@since
+ */
+public class RememberMeFilterBeanDefinitionParser extends AbstractBeanDefinitionParser {
+
+ 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;
+ }
+
+
+
+
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RememberMeServicesBeanDefinitionParser.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RememberMeServicesBeanDefinitionParser.java
new file mode 100644
index 0000000000..61fee2d62d
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/RememberMeServicesBeanDefinitionParser.java
@@ -0,0 +1,62 @@
+/**
+ *
+ */
+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_PROPERTY = "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_PROPERTY,
+ new RuntimeBeanReference(rememberMeServicesRef));
+ }
+ else {
+ // register a bean definition parse
+ RootBeanDefinition configurer = new RootBeanDefinition(RemeberMeServicesDependenciesConfigurer.class);
+ parserContext.getReaderContext().registerWithGeneratedName(configurer);
+ }
+ return rememberMeServicesBeanDef;
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java
new file mode 100644
index 0000000000..31113b0a31
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java
@@ -0,0 +1,33 @@
+/**
+ *
+ */
+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 'security' namespace.
+ * @author vpuri
+ *
+ * @since
+ */
+public class SecurityNamespaceHandler extends NamespaceHandlerSupport {
+
+ /**
+ * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
+ * 'context-integration', ' and '' elements.
+ */
+ public void init() {
+ registerBeanDefinitionParser("principal-repository", new PrincipalRepositoryBeanDefinitionParser());
+ registerBeanDefinitionParser("session-context-integration", new ContextIntegrationBeanDefinitionParser());
+ registerBeanDefinitionParser("authentication-repository", new AuthenticationRepositoryBeanDefinitionParser());
+ registerBeanDefinitionParser("authentication-mechanism", new AuthenticationMechanismBeanDefinitionParser());
+ registerBeanDefinitionParser("authentication-remember-me-services", new RememberMeServicesBeanDefinitionParser());
+ registerBeanDefinitionParser("authentication-remember-me-filter", new RememberMeFilterBeanDefinitionParser());
+ registerBeanDefinitionParser("logout-support", new LogoutFilterBeanDefinitionParser());
+ registerBeanDefinitionParser("exception-translation", new ExceptionTranslationFilterBeanDefinitionParser());
+ registerBeanDefinitionParser("authentication-form", new AuthenticationProcessingFilterBeanDefinitionParser());
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java
new file mode 100644
index 0000000000..6a226d53ed
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java
@@ -0,0 +1,239 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.ui.basicauth;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.acegisecurity.Authentication;
+import org.acegisecurity.AuthenticationException;
+import org.acegisecurity.AuthenticationManager;
+import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import org.acegisecurity.ui.AuthenticationDetailsSource;
+import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
+import org.acegisecurity.ui.rememberme.RememberMeServices;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.Ordered;
+import org.springframework.util.Assert;
+
+
+/**
+ * Processes a HTTP request's BASIC authorization headers, putting the result into the
+ * SecurityContextHolder.For a detailed background on what this filter is designed to process,
+ * refer to RFC 1945, Section 11.1. Any realm name presented in
+ * the HTTP request is ignored.
+ * In summary, this filter is responsible for processing any request that has a HTTP request header of
+ * Authorization with an authentication scheme of Basic and a Base64-encoded
+ * username:password token. For example, to authenticate user "Aladdin" with password "open sesame" the
+ * following header would be presented:
+ * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==.
+ * This filter can be used to provide BASIC authentication services to both remoting protocol clients (such as
+ * Hessian and SOAP) as well as standard user agents (such as Internet Explorer and Netscape).
+ * If authentication is successful, the resulting {@link Authentication} object will be placed into the
+ * SecurityContextHolder.
+ * If authentication fails and ignoreFailure is false (the default), an {@link
+ * AuthenticationEntryPoint} implementation is called. Usually this should be {@link BasicProcessingFilterEntryPoint},
+ * which will prompt the user to authenticate again via BASIC authentication.
+ * Basic authentication is an attractive protocol because it is simple and widely deployed. However, it still
+ * transmits a password in clear text and as such is undesirable in many situations. Digest authentication is also
+ * provided by Acegi Security and should be used instead of Basic authentication wherever possible. See {@link
+ * org.acegisecurity.ui.digestauth.DigestProcessingFilter}.
+ * Note that if a {@link #rememberMeServices} is set, this filter will automatically send back remember-me
+ * details to the client. Therefore, subsequent requests will not need to present a BASIC authentication header as
+ * they will be authenticated using the remember-me mechanism.
+ * Do not use this class directly. Instead configure web.xml to use the {@link
+ * org.acegisecurity.util.FilterToBeanProxy}.
+ *
+ * @author Ben Alex
+ * @version $Id: BasicProcessingFilter.java 1783 2007-02-23 19:21:44Z luke_t $
+ */
+public class BasicProcessingFilter implements Filter, InitializingBean, Ordered {
+ //~ Static fields/initializers =====================================================================================
+
+ private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
+
+ //~ Instance fields ================================================================================================
+
+ private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
+ private AuthenticationEntryPoint authenticationEntryPoint;
+ private AuthenticationManager authenticationManager;
+ private RememberMeServices rememberMeServices;
+ private boolean ignoreFailure = false;
+ private int order;
+
+ //~ Methods ========================================================================================================
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(this.authenticationManager, "An AuthenticationManager is required");
+ Assert.notNull(this.authenticationEntryPoint, "An AuthenticationEntryPoint is required");
+ }
+
+ public void destroy() {}
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+
+ if (!(request instanceof HttpServletRequest)) {
+ throw new ServletException("Can only process HttpServletRequest");
+ }
+
+ if (!(response instanceof HttpServletResponse)) {
+ throw new ServletException("Can only process HttpServletResponse");
+ }
+
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+ String header = httpRequest.getHeader("Authorization");
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authorization header: " + header);
+ }
+
+ if ((header != null) && header.startsWith("Basic ")) {
+ String base64Token = header.substring(6);
+ String token = new String(Base64.decodeBase64(base64Token.getBytes()));
+
+ String username = "";
+ String password = "";
+ int delim = token.indexOf(":");
+
+ if (delim != -1) {
+ username = token.substring(0, delim);
+ password = token.substring(delim + 1);
+ }
+
+ if (authenticationIsRequired(username)) {
+ UsernamePasswordAuthenticationToken authRequest =
+ new UsernamePasswordAuthenticationToken(username, password);
+ authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
+
+ Authentication authResult;
+
+ try {
+ authResult = authenticationManager.authenticate(authRequest);
+ } catch (AuthenticationException failed) {
+ // Authentication failed
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
+ }
+
+ SecurityContextHolder.getContext().setAuthentication(null);
+
+ if (rememberMeServices != null) {
+ rememberMeServices.loginFail(httpRequest, httpResponse);
+ }
+
+ if (ignoreFailure) {
+ chain.doFilter(request, response);
+ } else {
+ authenticationEntryPoint.commence(request, response, failed);
+ }
+
+ return;
+ }
+
+ // Authentication success
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authentication success: " + authResult.toString());
+ }
+
+ SecurityContextHolder.getContext().setAuthentication(authResult);
+
+ if (rememberMeServices != null) {
+ rememberMeServices.loginSuccess(httpRequest, httpResponse, authResult);
+ }
+ }
+ }
+
+ chain.doFilter(request, response);
+ }
+
+ private boolean authenticationIsRequired(String username) {
+ // Only reauthenticate if username doesn't match SecurityContextHolder and user isn't authenticated
+ // (see SEC-53)
+ Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
+
+ if(existingAuth == null || !existingAuth.isAuthenticated()) {
+ return true;
+ }
+
+ // Limit username comparison to providers which use usernames (ie UsernamePasswordAuthenticationToken)
+ // (see SEC-348)
+
+ if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public AuthenticationEntryPoint getAuthenticationEntryPoint() {
+ return authenticationEntryPoint;
+ }
+
+ public AuthenticationManager getAuthenticationManager() {
+ return authenticationManager;
+ }
+
+ public void init(FilterConfig arg0) throws ServletException {}
+
+ public boolean isIgnoreFailure() {
+ return ignoreFailure;
+ }
+
+ public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
+ Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
+ this.authenticationDetailsSource = authenticationDetailsSource;
+ }
+
+ public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
+ this.authenticationEntryPoint = authenticationEntryPoint;
+ }
+
+ public void setAuthenticationManager(AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+
+ public void setIgnoreFailure(boolean ignoreFailure) {
+ this.ignoreFailure = ignoreFailure;
+ }
+
+ public void setRememberMeServices(RememberMeServices rememberMeServices) {
+ this.rememberMeServices = rememberMeServices;
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java
new file mode 100644
index 0000000000..83f14c5fb3
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java
@@ -0,0 +1,89 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity.ui.basicauth;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.acegisecurity.AuthenticationException;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
+import org.acegisecurity.util.OrderedUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+import org.springframework.util.Assert;
+
+
+/**
+ * Used by the SecurityEnforcementFilter to commence authentication via the {@link
+ * BasicProcessingFilter}.Once a user agent is authenticated using BASIC authentication, logout requires that
+ * the browser be closed or an unauthorized (401) header be sent. The simplest way of achieving the latter is to call
+ * the {@link #commence(ServletRequest, ServletResponse, AuthenticationException)} method below. This will indicate to
+ * the browser its credentials are no longer authorized, causing it to prompt the user to login again.
+ *
+ * @author Ben Alex
+ * @version $Id: BasicProcessingFilterEntryPoint.java 1822 2007-05-17 12:20:16Z vishalpuri $
+ */
+public class BasicProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean, Ordered, ApplicationContextAware {
+ //~ Instance fields ================================================================================================
+
+ private static final int DEFAULT_ORDER = Integer.MAX_VALUE;
+ private String realmName;
+ private int order = DEFAULT_ORDER;
+ private ApplicationContext applicationContext;
+
+ //~ Methods ========================================================================================================
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.hasText(realmName, "realmName must be specified");
+ if (order == DEFAULT_ORDER) {
+ OrderedUtils.copyOrderFromOtherClass(BasicProcessingFilter.class, applicationContext, this, true);
+ }
+ }
+
+ public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException)
+ throws IOException, ServletException {
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\"");
+ httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
+ }
+
+ public String getRealmName() {
+ return realmName;
+ }
+
+ public void setRealmName(String realmName) {
+ this.realmName = realmName;
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/package.html b/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/package.html
new file mode 100644
index 0000000000..dcd7c31c91
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/ui/basicauth/package.html
@@ -0,0 +1,5 @@
+
+
+Authenticates HTTP BASIC authentication requests.
+
+
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/util/OrderedUtils.java b/sandbox/spring-security-config/src/main/java/org/acegisecurity/util/OrderedUtils.java
new file mode 100644
index 0000000000..0fc05337cc
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/util/OrderedUtils.java
@@ -0,0 +1,65 @@
+package org.acegisecurity.util;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.Ordered;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+/**
+ * Proivdes common logic for manipulating classes implementing the Spring
+ * {@link Ordered} interface.
+ *
+ * @author Ben Alex
+ */
+public abstract class OrderedUtils {
+ /**
+ * Introspects the application context for a single instance of sourceClass. If found, the order from the source
+ * class instance is copied into the destinationObject. If more than one instance of sourceClass
+ * is found, the method throws IllegalStateException.
+ *
+ * The destinationObject is required to provide a public setOrder(int) method to permit
+ * mutation of the order property.
+ *
+ * @param sourceClass to locate in the application context (must be assignable to Ordered)
+ * @param applicationContext to locate the class
+ * @param destinationObject to copy the order into (must provide public setOrder(int) method)
+ * @param skipIfMoreThanOneCandidateSourceClassInstance if the application context provides more than one potential source, skip modifications (if false, the first located matching source will be used)
+ * @return whether or not the destination class was updated
+ */
+ public static boolean copyOrderFromOtherClass(Class sourceClass, ApplicationContext applicationContext, Object destinationObject, boolean skipIfMoreThanOneCandidateSourceClassInstance) {
+ Assert.notNull(sourceClass, "Source class required");
+ Assert.notNull(applicationContext, "ApplicationContext required");
+ Assert.notNull(destinationObject, "Destination object required");
+ Assert.isAssignable(Ordered.class, sourceClass, "Source class " + sourceClass + " must be assignable to Ordered");
+ Map map = applicationContext.getBeansOfType(sourceClass);
+ if (map.size() == 0) {
+ return false;
+ } else if (map.size() > 1 && skipIfMoreThanOneCandidateSourceClassInstance) {
+ return false;
+ } else {
+ copyOrderFromOtherObject((Ordered)map.values().iterator().next(), destinationObject);
+ return true;
+ }
+ }
+
+ /**
+ * Copies the order property from the sourceObject into the destinationObject.
+ *
+ *
The destinationObject is required to provide a public setOrder(int) method to permit
+ * mutation of the order property.
+ *
+ * @param sourceObject to copy the order from
+ * @param destinationObject to copy the order into (must provide public setOrder(int) method)
+ */
+ public static void copyOrderFromOtherObject(Ordered sourceObject, Object destinationObject) {
+ Assert.notNull(sourceObject, "Source object required");
+ Assert.notNull(destinationObject, "Destination object required");
+ Method m = ReflectionUtils.findMethod(destinationObject.getClass(), "setOrder", new Class[] {int.class});
+ Assert.notNull(m, "Method setOrder(int) not found on " + destinationObject.getClass());
+ ReflectionUtils.invokeMethod(m, destinationObject, new Object[] {new Integer(sourceObject.getOrder())});
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/main/java/org/acegisecurity/util/package.html b/sandbox/spring-security-config/src/main/java/org/acegisecurity/util/package.html
new file mode 100644
index 0000000000..d845e7485f
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/java/org/acegisecurity/util/package.html
@@ -0,0 +1,5 @@
+
+
+General utility classes used throughout the Acegi Security System.
+
+
diff --git a/sandbox/spring-security-config/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd b/sandbox/spring-security-config/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd
new file mode 100644
index 0000000000..7bddc39c81
--- /dev/null
+++ b/sandbox/spring-security-config/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd
@@ -0,0 +1,478 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SecurityContext will be cloned from
+ the HttpSession. The default is to simply reference (ie
+ the default is 'false'. 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
+ HttpSession. 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 'HttpSession'.
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ " element.
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/AppTest.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/AppTest.java
new file mode 100644
index 0000000000..5ea0c789c6
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/AppTest.java
@@ -0,0 +1,38 @@
+package org.acegisecurity;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationMechanismNamespaceTests.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationMechanismNamespaceTests.java
new file mode 100644
index 0000000000..dcdd97b79c
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationMechanismNamespaceTests.java
@@ -0,0 +1,25 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import org.acegisecurity.providers.ProviderManager;
+import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import junit.framework.TestCase;
+
+/**
+ * @author vpuri
+ *
+ */
+public class AuthenticationMechanismNamespaceTests extends TestCase {
+ public void testParserDefaults() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "org/acegisecurity/config/remember-me-defaults.xml");
+ ProviderManager mgr = (ProviderManager) context.getBean("authenticationManager");
+ assertEquals(1, mgr.getProviders().size());
+ assertTrue(mgr.getProviders().get(0) instanceof DaoAuthenticationProvider);
+ }
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationProcessingFilterNamespaceTests.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationProcessingFilterNamespaceTests.java
new file mode 100644
index 0000000000..7a849525b6
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationProcessingFilterNamespaceTests.java
@@ -0,0 +1,25 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import junit.framework.TestCase;
+
+/**
+ * @author vpuri
+ *
+ */
+public class AuthenticationProcessingFilterNamespaceTests extends TestCase {
+
+ public void testAuthenticationFilterBeanDefinition() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "org/acegisecurity/config/authentication-form-filter.xml");
+ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) context
+ .getAutowireCapableBeanFactory();
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationRepositoryParserTest.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationRepositoryParserTest.java
new file mode 100644
index 0000000000..f91bc67d40
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/AuthenticationRepositoryParserTest.java
@@ -0,0 +1,120 @@
+/**
+ *
+ */
+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());
+
+ }
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/ExceptionTranslationParserTests.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/ExceptionTranslationParserTests.java
new file mode 100644
index 0000000000..f38282233a
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/ExceptionTranslationParserTests.java
@@ -0,0 +1,47 @@
+package org.acegisecurity.config;
+
+import javax.servlet.Filter;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.ui.ExceptionTranslationFilter;
+import org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint;
+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;
+
+public class ExceptionTranslationParserTests extends TestCase {
+
+ public void testParsingBeanReferences() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "org/acegisecurity/config/exception-translation-beanref.xml");
+ ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) context
+ .getAutowireCapableBeanFactory();
+ String[] beanNames = factory.getBeanNamesForType(Filter.class);
+ assertEquals(1, beanNames.length);
+ RootBeanDefinition def = (RootBeanDefinition) factory.getBeanDefinition(beanNames[0]);
+ assertEquals(ExceptionTranslationFilter.class.getName(), def.getBeanClassName());
+ // check collaborators
+ PropertyValue accessDeniedHandler = def.getPropertyValues().getPropertyValue("accessDeniedHandler");
+ assertNotNull(accessDeniedHandler);
+ assertEquals(accessDeniedHandler.getValue(), new RuntimeBeanReference("theBeanToUse"));
+ PropertyValue entryPoint = def.getPropertyValues().getPropertyValue("authenticationEntryPoint");
+ assertNotNull(entryPoint);
+ assertEquals(entryPoint.getValue(), new RuntimeBeanReference("authenticationProcessingFilterEntryPoint"));
+ }
+
+ public void testRuntimeBeanDependencies() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "org/acegisecurity/config/exception-translation-beanref.xml");
+ ExceptionTranslationFilter filter = (ExceptionTranslationFilter) context.getBean("exceptionTranslationFilter");
+ AuthenticationProcessingFilterEntryPoint entryPoint = (AuthenticationProcessingFilterEntryPoint) filter
+ .getAuthenticationEntryPoint();
+ assertEquals("/acegilogin.jsp", entryPoint.getLoginFormUrl());
+ assertFalse(entryPoint.getForceHttps());
+
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/HttpSessionContextIntegrationParserTest.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/HttpSessionContextIntegrationParserTest.java
new file mode 100644
index 0000000000..09f05815a6
--- /dev/null
+++ b/sandbox/spring-security-config/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());
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/LogoutFilterBeanDefinitionParserTests.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/LogoutFilterBeanDefinitionParserTests.java
new file mode 100644
index 0000000000..68a1b7b8ef
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/LogoutFilterBeanDefinitionParserTests.java
@@ -0,0 +1,29 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.ui.logout.LogoutHandler;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @author vpuri
+ *
+ */
+public class LogoutFilterBeanDefinitionParserTests extends TestCase {
+
+ public void testLogoutFilter() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "org/acegisecurity/config/logout-filter-with-handlers.xml");
+ ConfigurableListableBeanFactory bf = (ConfigurableListableBeanFactory) context.getAutowireCapableBeanFactory();
+ Map m = bf.getBeansOfType(LogoutHandler.class);
+ assertEquals(2, m.size());
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/NamespaceTests.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/NamespaceTests.java
new file mode 100644
index 0000000000..235cba6871
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/NamespaceTests.java
@@ -0,0 +1,22 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import junit.framework.TestCase;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @author vpuri
+ *
+ */
+public class NamespaceTests extends TestCase {
+
+
+ public void testPass() {
+ ApplicationContext c = new ClassPathXmlApplicationContext("org/acegisecurity/config/applicationContext-acegi-security.xml");
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/PrincipalRepositoryNamespaceTests.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/PrincipalRepositoryNamespaceTests.java
new file mode 100644
index 0000000000..3640d936e4
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/PrincipalRepositoryNamespaceTests.java
@@ -0,0 +1,66 @@
+/**
+ *
+ */
+package org.acegisecurity.config;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.GrantedAuthority;
+import org.acegisecurity.GrantedAuthorityImpl;
+import org.acegisecurity.userdetails.User;
+import org.acegisecurity.userdetails.UserDetailsService;
+import org.acegisecurity.userdetails.memory.InMemoryDaoImpl;
+import org.acegisecurity.userdetails.memory.UserMap;
+import org.springframework.beans.PropertyValue;
+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;
+
+/**
+ * @author vpuri
+ *
+ */
+public class PrincipalRepositoryNamespaceTests extends TestCase {
+
+ public void testParserWithUserDefinition() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "org/acegisecurity/config/principal-repository-user-map.xml");
+
+ ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) context
+ .getAutowireCapableBeanFactory();
+
+ String[] names = clbf.getBeanNamesForType(UserDetailsService.class);
+ assertEquals(1, names.length);
+
+ RootBeanDefinition definition = (RootBeanDefinition) clbf.getBeanDefinition(names[0]);
+ assertEquals(InMemoryDaoImpl.class, definition.getBeanClass());
+
+ UserMap map = new UserMap();
+
+ GrantedAuthority[] authotities = { new GrantedAuthorityImpl("ROLE_YO"), new GrantedAuthorityImpl("ROLE_YOYO") };
+
+ User user = new User("vishal", "nottellingya", true, true, true, true, authotities);
+
+ map.addUser(user);
+
+ assertPropertyValues(map, definition, "userMap");
+
+ }
+
+ private void assertPropertyValues(UserMap assertionValue, RootBeanDefinition definition, String property) {
+ PropertyValue propertyValue = definition.getPropertyValues().getPropertyValue(property);
+ assertNotNull(propertyValue);
+ assertTrue(propertyValue.getValue() instanceof UserMap);
+ UserMap users = (UserMap) propertyValue.getValue();
+ assertTrue(assertionValue.getUserCount() == users.getUserCount());
+ assertEquals(assertionValue.getUser("vishal"), users.getUser("vishal"));
+ assertTrue(users.getUser("vishal").isEnabled());
+ assertTrue(users.getUser("vishal").isAccountNonExpired());
+ assertTrue(users.getUser("vishal").isAccountNonLocked());
+ assertTrue(users.getUser("vishal").isCredentialsNonExpired());
+ assertEquals(2, users.getUser("vishal").getAuthorities().length);
+ assertEquals(new GrantedAuthorityImpl("ROLE_YO"), users.getUser("vishal").getAuthorities()[0]);
+ assertEquals(new GrantedAuthorityImpl("ROLE_YOYO"), users.getUser("vishal").getAuthorities()[1]);
+ }
+}
diff --git a/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/RememberMeBeanDefinitionParserTest.java b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/RememberMeBeanDefinitionParserTest.java
new file mode 100644
index 0000000000..a8a2e9e7db
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/java/org/acegisecurity/config/RememberMeBeanDefinitionParserTest.java
@@ -0,0 +1,19 @@
+package org.acegisecurity.config;
+
+import junit.framework.TestCase;
+
+import org.acegisecurity.providers.ProviderManager;
+import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class RememberMeBeanDefinitionParserTest extends TestCase {
+
+ public void testParserDefaults() {
+ ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/remember-me-defaults.xml");
+ ProviderManager mgr = (ProviderManager)context.getBean("authenticationManager");
+ assertEquals(1, mgr.getProviders().size());
+ assertTrue(mgr.getProviders().get(0) instanceof DaoAuthenticationProvider);
+ }
+
+}
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/applicationContext-acegi-security.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/applicationContext-acegi-security.xml
new file mode 100644
index 0000000000..1a00e51fc6
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/applicationContext-acegi-security.xml
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+
+ CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+ PATTERN_TYPE_APACHE_ANT
+ /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+ PATTERN_TYPE_APACHE_ANT
+ /secure/extreme/**=ROLE_SUPERVISOR
+ /secure/**=IS_AUTHENTICATED_REMEMBERED
+ /**=IS_AUTHENTICATED_ANONYMOUSLY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-basic-filter.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-basic-filter.xml
new file mode 100644
index 0000000000..5eca57c38b
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-basic-filter.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-beanRef-attributes.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-beanRef-attributes.xml
new file mode 100644
index 0000000000..43b4967648
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-beanRef-attributes.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
+
+
+ 12345
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-dao-defaults.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-dao-defaults.xml
new file mode 100644
index 0000000000..6de9406972
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-dao-defaults.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
+
+
+ 12345
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-defaults.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-defaults.xml
new file mode 100644
index 0000000000..d4a24931d9
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-defaults.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-form-filter.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-form-filter.xml
new file mode 100644
index 0000000000..3187c14593
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-form-filter.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
+
+
+
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-innerbeans.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-innerbeans.xml
new file mode 100644
index 0000000000..f096d01e78
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/authentication-innerbeans.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/exception-translation-autodetect-handler.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/exception-translation-autodetect-handler.xml
new file mode 100644
index 0000000000..2499d50fa9
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/exception-translation-autodetect-handler.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /acegilogin.jsp
+
+
+ false
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/exception-translation-beanref.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/exception-translation-beanref.xml
new file mode 100644
index 0000000000..67d5426a59
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/exception-translation-beanref.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /acegilogin.jsp
+
+
+ false
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/logout-filter-with-handlers.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/logout-filter-with-handlers.xml
new file mode 100644
index 0000000000..cf1168fbb1
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/logout-filter-with-handlers.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-jdbc.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-jdbc.xml
new file mode 100644
index 0000000000..543b986f32
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-jdbc.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-properties.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-properties.xml
new file mode 100644
index 0000000000..dfe21d29e4
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-properties.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-user-map.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-user-map.xml
new file mode 100644
index 0000000000..4e035ff1d6
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/principal-repository-user-map.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/remember-me-defaults.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/remember-me-defaults.xml
new file mode 100644
index 0000000000..fc11aa49fa
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/remember-me-defaults.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.hsqldb.jdbcDriver
+
+
+ jdbc:hsqldb:mem:test
+
+
+
+ sa
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/security-autoconfig-autodetect.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/security-autoconfig-autodetect.xml
new file mode 100644
index 0000000000..2a9ea4358e
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/security-autoconfig-autodetect.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/security-namespaces.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/security-namespaces.xml
new file mode 100644
index 0000000000..40d8a49575
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/security-namespaces.xml
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ **/*=AUTODETECT_ALL_ORDERED_FILTERS
+ **/*=filter1,filter2,filter3
+
+
+
+
+
+
+ t
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/session-context-integration-defaults.xml b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/session-context-integration-defaults.xml
new file mode 100644
index 0000000000..1ba0d6483e
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/session-context-integration-defaults.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/user.properties b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/user.properties
new file mode 100644
index 0000000000..cd5f8e8b31
--- /dev/null
+++ b/sandbox/spring-security-config/src/test/resources/org/acegisecurity/config/user.properties
@@ -0,0 +1,2 @@
+vishal=ity,ROLE_ADMIN
+ity=vishal,ROLE_TELLER