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