1
0
mirror of synced 2026-08-05 09:47:05 +00:00

Provide a proxy so filters can be loaded directly from the application context.

This commit is contained in:
Ben Alex
2004-04-16 06:31:48 +00:00
parent 7b59d5f189
commit 38835da164
22 changed files with 976 additions and 862 deletions
@@ -22,16 +22,10 @@ import net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -65,72 +59,79 @@ import javax.servlet.http.HttpServletResponse;
* </p>
*
* <p>
* This filter works with a <code>FilterSecurityInterceptor</code> instance. By
* default, at init time, the filter will use Spring's {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* method to obtain an ApplicationContext instance, inside which must be a
* configured <code>FilterSecurityInterceptor</code> instance. In the case
* where it is desireable for this filter to instantiate its own
* ApplicationContext instance from which to obtain the
* <code>FilterSecurityInterceptor</code>, the location of the config for this
* context may be specified with the optional
* <code>contextConfigLocation</code> init param.
* </p>
*
* <p>
* To use this filter, it is necessary to specify the following filter
* initialization parameters:
* </p>
*
* <ul>
* <li>
* <code>filterSecurityInterceptor</code> indicates the
* <code>FilterSecurityInterceptor</code> to delegate HTTP security decisions
* to.
* </li>
* <li>
* <code>loginFormUrl</code> indicates the URL that should be used for
* redirection if an <code>AuthenticationException</code> is detected.
* </li>
* <li>
* <code>contextConfigLocation</code> (optional, normally not used), indicates
* the path to an application context that contains a properly configured
* <code>FilterSecurityInterceptor</code>. If not specified, {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* will be used to obtain the context.
* </li>
* </ul>
*
* <P>
* <B>Do not use this class directly.</B> Instead configure
* <code>web.xml</code> to use the {@link
* net.sf.acegisecurity.util.FilterToBeanProxy}.
* </p>
*
* @author Ben Alex
* @author colin sampaleanu
* @version $Id$
*/
public class SecurityEnforcementFilter implements Filter {
public class SecurityEnforcementFilter implements Filter, InitializingBean {
//~ Static fields/initializers =============================================
/**
* Name of (optional) servlet filter parameter that can specify the config
* location for a new ApplicationContext used to config this filter.
*/
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
private static final Log logger = LogFactory.getLog(SecurityEnforcementFilter.class);
//~ Instance fields ========================================================
protected FilterSecurityInterceptor securityInterceptor;
protected FilterSecurityInterceptor filterSecurityInterceptor;
/**
* The URL that should be used for redirection if an
* <code>AuthenticationException</code> is detected.
*/
protected String loginFormUrl;
private ApplicationContext ctx;
private boolean ourContext = false;
//~ Methods ================================================================
public void destroy() {
if (ourContext && ctx instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) ctx).close();
public void setFilterSecurityInterceptor(
FilterSecurityInterceptor filterSecurityInterceptor) {
this.filterSecurityInterceptor = filterSecurityInterceptor;
}
public FilterSecurityInterceptor getFilterSecurityInterceptor() {
return filterSecurityInterceptor;
}
public void setLoginFormUrl(String loginFormUrl) {
this.loginFormUrl = loginFormUrl;
}
public String getLoginFormUrl() {
return loginFormUrl;
}
public void afterPropertiesSet() throws Exception {
if ((loginFormUrl == null) || "".equals(loginFormUrl)) {
throw new IllegalArgumentException("loginFormUrl must be specified");
}
if (filterSecurityInterceptor == null) {
throw new IllegalArgumentException(
"filterSecurityInterceptor must be specified");
}
}
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
@@ -144,7 +145,7 @@ public class SecurityEnforcementFilter implements Filter {
FilterInvocation fi = new FilterInvocation(request, response, chain);
try {
securityInterceptor.invoke(fi);
filterSecurityInterceptor.invoke(fi);
if (logger.isDebugEnabled()) {
logger.debug("Chain processed normally");
@@ -174,49 +175,5 @@ public class SecurityEnforcementFilter implements Filter {
}
}
public void init(FilterConfig filterConfig) throws ServletException {
String appContextLocation = filterConfig.getInitParameter(CONFIG_LOCATION_PARAM);
if ((appContextLocation != null) && (appContextLocation.length() > 0)) {
ourContext = true;
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate "
+ appContextLocation);
}
}
loginFormUrl = filterConfig.getInitParameter("loginFormUrl");
if ((loginFormUrl == null) || "".equals(loginFormUrl)) {
throw new ServletException("loginFormUrl must be specified");
}
try {
if (!ourContext) {
ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(filterConfig
.getServletContext());
} else {
ctx = new ClassPathXmlApplicationContext(appContextLocation);
}
} catch (RuntimeException e) {
throw new ServletException(
"Error obtaining/creating ApplicationContext for config. Must be stored in ServletContext, or optionally '"
+ CONFIG_LOCATION_PARAM
+ "' param may be used to allow creation of new context by this filter. See root error for additional details",
e);
}
Map beans = ctx.getBeansOfType(FilterSecurityInterceptor.class, true,
true);
if (beans.size() == 0) {
throw new ServletException(
"Bean context must contain at least one bean of type FilterSecurityInterceptor");
}
String beanName = (String) beans.keySet().iterator().next();
securityInterceptor = (FilterSecurityInterceptor) beans.get(beanName);
}
public void init(FilterConfig filterConfig) throws ServletException {}
}
@@ -25,16 +25,10 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -87,63 +81,44 @@ import javax.servlet.http.HttpServletResponse;
* sent with a request, it should return a 403 (forbidden) response.</I>".
* </p>
*
* <p>
* This filter works with an {@link AuthenticationManager} which is used to
* process each authentication request. By default, at init time, the filter
* will use Spring's {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* method to obtain an ApplicationContext instance, inside which must be a
* configured AuthenticationManager instance. In the case where it is
* desirable for this filter to instantiate its own ApplicationContext
* instance from which to obtain the AuthenticationManager, the location of
* the config for this context may be specified with the optional
* <code>contextConfigLocation</code> init param.
* <P>
* <B>Do not use this class directly.</B> Instead configure
* <code>web.xml</code> to use the {@link
* net.sf.acegisecurity.util.FilterToBeanProxy}.
* </p>
*
* <p>
* To use this filter, it is necessary to specify the following filter
* initialization parameters:
* </p>
*
* <ul>
* <li>
* <code>contextConfigLocation</code> (optional, normally not used), indicates
* the path to an application context that contains an {@link
* AuthenticationManager} which should be used to process each authentication
* request. If not specified, {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* will be used to obtain the context.
* </li>
* </ul>
*
*
* @author Ben Alex
* @version $Id$
*/
public class BasicProcessingFilter implements Filter {
public class BasicProcessingFilter implements Filter, InitializingBean {
//~ Static fields/initializers =============================================
/**
* Name of (optional) servlet filter parameter that can specify the config
* location for a new ApplicationContext used to config this filter.
*/
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
//~ Instance fields ========================================================
private ApplicationContext ctx;
private AuthenticationManager authenticationManager;
private boolean ourContext = false;
//~ Methods ================================================================
public void destroy() {
if (ourContext && ctx instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) ctx).close();
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void afterPropertiesSet() throws Exception {
if (this.authenticationManager == null) {
throw new IllegalArgumentException(
"An AuthenticationManager is required");
}
}
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
@@ -208,42 +183,5 @@ public class BasicProcessingFilter implements Filter {
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String appContextLocation = filterConfig.getInitParameter(CONFIG_LOCATION_PARAM);
if ((appContextLocation != null) && (appContextLocation.length() > 0)) {
ourContext = true;
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate "
+ appContextLocation);
}
}
try {
if (!ourContext) {
ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(filterConfig
.getServletContext());
} else {
ctx = new ClassPathXmlApplicationContext(appContextLocation);
}
} catch (RuntimeException e) {
throw new ServletException(
"Error obtaining/creating ApplicationContext for config. Must be stored in ServletContext, or optionally '"
+ CONFIG_LOCATION_PARAM
+ "' param may be used to allow creation of new context by this filter. See root error for additional details",
e);
}
Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
if (beans.size() == 0) {
throw new ServletException(
"Bean context must contain at least one bean of type AuthenticationManager");
}
String beanName = (String) beans.keySet().iterator().next();
authenticationManager = (AuthenticationManager) beans.get(beanName);
}
public void init(FilterConfig arg0) throws ServletException {}
}
@@ -23,16 +23,10 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -70,21 +64,7 @@ import javax.servlet.http.HttpServletResponse;
* </p>
*
* <p>
* This filter works with an {@link AuthenticationManager} which is used to
* process each authentication request. By default, at init time, the filter
* will use Spring's {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* method to obtain an ApplicationContext instance, inside which must be a
* configured AuthenticationManager instance. In the case where it is
* desirable for this filter to instantiate its own ApplicationContext
* instance from which to obtain the AuthenticationManager, the location of
* the config for this context may be specified with the optional
* <code>contextConfigLocation</code> init param.
* </p>
*
* <p>
* To use this filter, it is necessary to specify the following filter
* initialization parameters:
* To use this filter, it is necessary to specify the following properties:
* </p>
*
* <ul>
@@ -104,29 +84,21 @@ import javax.servlet.http.HttpServletResponse;
* respond to. This parameter is optional, and defaults to
* <code>/j_acegi_security_check</code>.
* </li>
* <li>
* <code>contextConfigLocation</code> (optional, normally not used), indicates
* the path to an application context that contains an {@link
* AuthenticationManager} which should be used to process each authentication
* request. If not specified, {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* will be used to obtain the context.
* </li>
* </ul>
*
* <P>
* <B>Do not use this class directly.</B> Instead configure
* <code>web.xml</code> to use the {@link
* net.sf.acegisecurity.util.FilterToBeanProxy}.
* </p>
*
* @author Ben Alex
* @author Colin Sampaleanu
* @version $Id$
*/
public class AuthenticationProcessingFilter implements Filter {
public class AuthenticationProcessingFilter implements Filter, InitializingBean {
//~ Static fields/initializers =============================================
/**
* Name of (optional) servlet filter parameter that can specify the config
* location for a new ApplicationContext used to config this filter.
*/
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL";
public static final String ACEGI_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password";
@@ -135,7 +107,6 @@ public class AuthenticationProcessingFilter implements Filter {
//~ Instance fields ========================================================
private ApplicationContext ctx;
private AuthenticationManager authenticationManager;
/** Where to redirect the browser to if authentication fails */
@@ -151,17 +122,68 @@ public class AuthenticationProcessingFilter implements Filter {
* The URL destination that this filter intercepts and processes (usually
* <code>/j_acegi_security_check</code>)
*/
private String filterProcessesUrl;
private boolean ourContext = false;
private String filterProcessesUrl = "/j_acegi_security_check";
//~ Methods ================================================================
public void destroy() {
if (ourContext && ctx instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) ctx).close();
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
this.authenticationFailureUrl = authenticationFailureUrl;
}
public String getAuthenticationFailureUrl() {
return authenticationFailureUrl;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
public void afterPropertiesSet() throws Exception {
if ((filterProcessesUrl == null) || "".equals(filterProcessesUrl)) {
throw new IllegalArgumentException(
"filterProcessesUrl must be specified");
}
if ((defaultTargetUrl == null) || "".equals(defaultTargetUrl)) {
throw new IllegalArgumentException(
"defaultTargetUrl must be specified");
}
if ((authenticationFailureUrl == null)
|| "".equals(authenticationFailureUrl)) {
throw new IllegalArgumentException(
"authenticationFailureUrl must be specified");
}
if (authenticationManager == null) {
throw new IllegalArgumentException(
"authenticationManager must be specified");
}
}
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
@@ -245,63 +267,5 @@ public class AuthenticationProcessingFilter implements Filter {
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String appContextLocation = filterConfig.getInitParameter(CONFIG_LOCATION_PARAM);
if ((appContextLocation != null) && (appContextLocation.length() > 0)) {
ourContext = true;
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate "
+ appContextLocation);
}
}
defaultTargetUrl = filterConfig.getInitParameter("defaultTargetUrl");
if ((defaultTargetUrl == null) || "".equals(defaultTargetUrl)) {
throw new ServletException("defaultTargetUrl must be specified");
}
authenticationFailureUrl = filterConfig.getInitParameter(
"authenticationFailureUrl");
if ((authenticationFailureUrl == null)
|| "".equals(authenticationFailureUrl)) {
throw new ServletException(
"authenticationFailureUrl must be specified");
}
filterProcessesUrl = filterConfig.getInitParameter("filterProcessesUrl");
if ((filterProcessesUrl == null) || "".equals(filterProcessesUrl)) {
filterProcessesUrl = "/j_acegi_security_check";
}
try {
if (!ourContext) {
ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(filterConfig
.getServletContext());
} else {
ctx = new ClassPathXmlApplicationContext(appContextLocation);
}
} catch (RuntimeException e) {
throw new ServletException(
"Error obtaining/creating ApplicationContext for config. Must be stored in ServletContext, or optionally '"
+ CONFIG_LOCATION_PARAM
+ "' param may be used to allow creation of new context by this filter. See root error for additional details",
e);
}
Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
if (beans.size() == 0) {
throw new ServletException(
"Bean context must contain at least one bean of type AuthenticationManager");
}
String beanName = (String) beans.keySet().iterator().next();
authenticationManager = (AuthenticationManager) beans.get(beanName);
}
public void init(FilterConfig filterConfig) throws ServletException {}
}
@@ -0,0 +1,164 @@
/* Copyright 2004 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 net.sf.acegisecurity.util;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Delegates <code>Filter</code> requests to a Spring-managed bean.
*
* <p>
* This class acts as a proxy on behalf of a target <code>Filter</code> that is
* defined in the Spring bean context. It is necessary to specify which target
* <code>Filter</code> should be proxied as a filter initialization parameter.
* </p>
*
* <p>
* On filter initialisation, the class will use Spring's {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* method to obtain an <code>ApplicationContext</code> instance. It will
* expect to find the target <code>Filter</code> in this
* <code>ApplicationContext</code>.
* </p>
*
* <p>
* To use this filter, it is necessary to specify the following filter
* initialization parameters:
* </p>
*
* <ul>
* <li>
* <code>targetClass</code> indicates the class of the target
* <code>Filter</code> defined in the bean context. The only requirements are
* that this target class implements the <code>javax.servlet.Filter</code>
* interface and at least one instance is available in the
* <code>ApplicationContext</code>.
* </li>
* <li>
* <code>targetBean</code> (optional) indicates the bean name of the target
* class. This parameter should be specified if there is more than one bean in
* the <code>ApplicationContext</code> of the same type as defined by the
* <code>targetClass</code> parameter.
* </li>
* </ul>
*
*
* @author Ben Alex
* @version $Id$
*/
public class FilterToBeanProxy implements Filter {
//~ Instance fields ========================================================
private Filter delegate;
//~ Methods ================================================================
public void destroy() {
delegate.destroy();
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
delegate.doFilter(request, response, chain);
}
public void init(FilterConfig filterConfig) throws ServletException {
String targetClassString = filterConfig.getInitParameter("targetClass");
if ((targetClassString == null) || "".equals(targetClassString)) {
throw new ServletException("targetClass must be specified");
}
Class targetClass;
try {
targetClass = Thread.currentThread().getContextClassLoader()
.loadClass(targetClassString);
} catch (ClassNotFoundException ex) {
throw new ServletException("Class of type " + targetClassString
+ " not found in classloader");
}
String targetBean = filterConfig.getInitParameter("targetBean");
if ("".equals(targetBean)) {
targetBean = null;
}
ApplicationContext ctx = this.getContext(filterConfig);
Map beans = ctx.getBeansOfType(targetClass, true, true);
if (beans.size() == 0) {
throw new ServletException(
"Bean context must contain at least one bean of type "
+ targetClassString);
}
String beanName = null;
if (targetBean == null) {
// Use first bean found
beanName = (String) beans.keySet().iterator().next();
} else {
// Use the requested bean, providing it can be found
if (beans.containsKey(targetBean)) {
beanName = targetBean;
} else {
throw new ServletException("Bean with name '" + targetBean
+ "' cannot be found in bean context");
}
}
Object object = beans.get(beanName);
if (!(object instanceof Filter)) {
throw new ServletException("Bean '" + beanName
+ "' does not implement javax.servlet.Filter");
}
delegate = (Filter) object;
delegate.init(filterConfig);
}
/**
* Allows test cases to override where application context obtained from.
*
* @param filterConfig which can be used to find the
* <code>ServletContext</code>
*
* @return the Spring application context
*/
protected ApplicationContext getContext(FilterConfig filterConfig) {
return WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig
.getServletContext());
}
}
@@ -0,0 +1,5 @@
<html>
<body>
General utility classes used throughout the Acegi Security System.
</body>
</html>
@@ -19,7 +19,6 @@ import junit.framework.TestCase;
import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.MockHttpSession;
@@ -75,9 +74,11 @@ public class SecurityEnforcementFilterTests extends TestCase {
false);
// Test
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(interceptor);
filter.setLoginFormUrl("/login.jsp");
MockHttpServletResponse response = new MockHttpServletResponse();
SecurityEnforcementFilter filter = new MockSecurityEnforcementFilter(interceptor,
"/login.jsp");
filter.doFilter(request, response, chain);
assertEquals(403, response.getError());
}
@@ -108,6 +109,16 @@ public class SecurityEnforcementFilterTests extends TestCase {
}
}
public void testGettersSetters() {
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
false, false));
assertTrue(filter.getFilterSecurityInterceptor() != null);
filter.setLoginFormUrl("/u");
assertEquals("/u", filter.getLoginFormUrl());
}
public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWhenAuthenticationException()
throws Exception {
// Setup our HTTP request
@@ -123,93 +134,42 @@ public class SecurityEnforcementFilterTests extends TestCase {
true);
// Test
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(interceptor);
filter.setLoginFormUrl("/login.jsp");
filter.afterPropertiesSet();
MockHttpServletResponse response = new MockHttpServletResponse();
SecurityEnforcementFilter filter = new MockSecurityEnforcementFilter(interceptor,
"/login.jsp");
filter.doFilter(request, response, chain);
assertEquals("/login.jsp", response.getRedirect());
assertEquals("/secure/page.html",
request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY));
}
public void testStartupDetectsInvalidcontextConfigLocation()
public void testStartupDetectsMissingFilterSecurityInterceptor()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("loginFormUrl", "/login.jsp");
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/intercept/web/securityfiltertest-invalid.xml");
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setLoginFormUrl("/login.jsp");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Bean context must contain at least one bean of type FilterSecurityInterceptor",
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("filterSecurityInterceptor must be specified",
expected.getMessage());
}
}
public void testStartupDetectsMissingAppContext() throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("loginFormUrl", "/login.jsp");
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Error obtaining/creating ApplicationContext for config."));
}
config.setInitParmeter("contextConfigLocation", "");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Error obtaining/creating ApplicationContext for config."));
}
}
public void testStartupDetectsMissingInvalidcontextConfigLocation()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("loginFormUrl", "/login.jsp");
config.setInitParmeter("contextConfigLocation", "DOES_NOT_EXIST");
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Cannot locate"));
}
}
public void testStartupDetectsMissingLoginFormUrl()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/intercept/web/securityfiltertest-valid.xml");
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
false, false));
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("loginFormUrl must be specified", expected.getMessage());
}
config.setInitParmeter("loginFormUrl", "");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("loginFormUrl must be specified", expected.getMessage());
}
}
@@ -228,22 +188,19 @@ public class SecurityEnforcementFilterTests extends TestCase {
false);
// Test
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(interceptor);
filter.setLoginFormUrl("/login.jsp");
MockHttpServletResponse response = new MockHttpServletResponse();
SecurityEnforcementFilter filter = new MockSecurityEnforcementFilter(interceptor,
"/login.jsp");
filter.doFilter(request, response, chain);
}
public void testSuccessfulStartupAndShutdownDown()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/intercept/web/securityfiltertest-valid.xml");
config.setInitParmeter("loginFormUrl", "/login.jsp");
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.init(config);
filter.init(null);
filter.destroy();
assertTrue(true);
}
@@ -298,17 +255,4 @@ public class SecurityEnforcementFilterTests extends TestCase {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
}
}
private class MockSecurityEnforcementFilter
extends SecurityEnforcementFilter {
public MockSecurityEnforcementFilter(
FilterSecurityInterceptor securityInterceptor, String loginFormUrl) {
super.securityInterceptor = securityInterceptor;
super.loginFormUrl = loginFormUrl;
}
private MockSecurityEnforcementFilter() {
super();
}
}
}
@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
* Copyright 2004 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.
*
*
* $Id$
-->
<beans>
<bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
dianne=emu,ROLE_TELLER
scott=wombat,ROLE_TELLER
peter=opal,disabled,ROLE_TELLER
</value>
</property>
</bean>
<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
</bean>
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="runAsManager"><ref bean="runAsManager"/></property>
<property name="objectDefinitionSource">
<value>
\A/secure/super.*\Z=ROLE_WE_DONT_HAVE
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
</value>
</property>
</bean>
</beans>
@@ -18,6 +18,7 @@ package net.sf.acegisecurity.ui.basicauth;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.MockAuthenticationManager;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
@@ -26,6 +27,9 @@ import net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter;
import org.apache.commons.codec.binary.Base64;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.HashMap;
@@ -102,23 +106,32 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession());
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/basicauth/filtertest-valid.xml");
BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
"basicProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
}
public void testGettersSetters() {
BasicProcessingFilter filter = new BasicProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
assertTrue(filter.getAuthenticationManager() != null);
}
public void testInvalidBasicAuthorizationTokenIsIgnored()
throws Exception {
// Setup our HTTP request
@@ -131,17 +144,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession());
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/basicauth/filtertest-valid.xml");
BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
"basicProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
@@ -159,17 +175,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession());
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/basicauth/filtertest-valid.xml");
BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
"basicProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
@@ -189,77 +208,38 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession());
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/basicauth/filtertest-valid.xml");
BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
"basicProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
}
public void testStartupDetectsInvalidContextConfigLocation()
public void testStartupDetectsMissingAuthenticationManager()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-invalid.xml");
BasicProcessingFilter filter = new BasicProcessingFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Bean context must contain at least one bean of type AuthenticationManager",
BasicProcessingFilter filter = new BasicProcessingFilter();
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("An AuthenticationManager is required",
expected.getMessage());
}
}
public void testStartupDetectsMissingAppContext() throws Exception {
MockFilterConfig config = new MockFilterConfig();
BasicProcessingFilter filter = new BasicProcessingFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Error obtaining/creating ApplicationContext for config."));
}
config.setInitParmeter("contextConfigLocation", "");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Error obtaining/creating ApplicationContext for config."));
}
}
public void testStartupDetectsMissingInvalidContextConfigLocation()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation", "DOES_NOT_EXIST");
BasicProcessingFilter filter = new BasicProcessingFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Cannot locate"));
}
}
public void testSuccessLoginThenFailureLoginResultsInSessionLoosingToken()
throws Exception {
// Setup our HTTP request
@@ -272,17 +252,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession());
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/basicauth/filtertest-valid.xml");
BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
"basicProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
@@ -306,7 +289,6 @@ public class BasicProcessingFilterTests extends TestCase {
response = new MockHttpServletResponse();
// Test
filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
@@ -325,17 +307,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession());
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/basicauth/filtertest-valid.xml");
BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
"basicProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
// Setup our expectation that the filter chain will not be invoked, as we get a 403 forbidden response
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
@@ -33,6 +33,22 @@
</property>
</bean>
<!-- The authentication manager is deliberately missing in order to test error detection -->
<!-- Authentication provider that queries our data access object -->
<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
</bean>
<!-- The authentication manager that iterates through our only authentication provider -->
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
</bean>
</beans>
@@ -18,11 +18,15 @@ package net.sf.acegisecurity.ui.webapp;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.MockAuthenticationManager;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.MockHttpSession;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import javax.servlet.Filter;
@@ -100,19 +104,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"WRONG_PASSWORD");
request.setServletPath("/j_acegi_security_check");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will not be invoked, as we redirect to authenticationFailureUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
System.out.println(response.getRedirect());
@@ -129,22 +134,25 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"marissa");
request.setParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY,
"koala");
request.setServletPath("/j_my_security_check");
request.setServletPath("/j_THIS_IS_MY_security_check");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Must override the XML defined authenticationProcessesUrl
filter.setFilterProcessesUrl("/j_THIS_IS_MY_security_check");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
config.setInitParmeter("filterProcessesUrl", "/j_my_security_check");
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/", response.getRedirect());
@@ -154,6 +162,21 @@ public class AuthenticationProcessingFilterTests extends TestCase {
.toString());
}
public void testGettersSetters() {
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationFailureUrl("/x");
assertEquals("/x", filter.getAuthenticationFailureUrl());
filter.setAuthenticationManager(new MockAuthenticationManager());
assertTrue(filter.getAuthenticationManager() != null);
filter.setDefaultTargetUrl("/default");
assertEquals("/default", filter.getDefaultTargetUrl());
filter.setFilterProcessesUrl("/p");
assertEquals("/p", filter.getFilterProcessesUrl());
}
public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl()
throws Exception {
// Setup our HTTP request
@@ -161,18 +184,19 @@ public class AuthenticationProcessingFilterTests extends TestCase {
new MockHttpSession());
request.setServletPath("/j_some_other_url");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will be invoked, as should just proceed with chain
MockFilterChain chain = new MockFilterChain(true);
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request,
new MockHttpServletResponse(), chain);
}
@@ -188,19 +212,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"koala");
request.setServletPath("/j_acegi_security_check");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/", response.getRedirect());
@@ -220,19 +245,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
null);
request.setServletPath("/j_acegi_security_check");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/failed.jsp", response.getRedirect());
@@ -249,138 +275,88 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"koala");
request.setServletPath("/j_acegi_security_check");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/failed.jsp", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
}
public void testStartupDetectsInvalidcontextConfigLocation()
public void testStartupDetectsInvalidAuthenticationFailureUrl()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-invalid.xml");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setDefaultTargetUrl("/");
filter.setFilterProcessesUrl("/j_acegi_security_check");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Bean context must contain at least one bean of type AuthenticationManager",
expected.getMessage());
}
}
public void testStartupDetectsMissingAppContext() throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Error obtaining/creating ApplicationContext for config."));
}
config.setInitParmeter("contextConfigLocation", "");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Error obtaining/creating ApplicationContext for config."));
}
}
public void testStartupDetectsMissingAuthenticationFailureUrl()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("authenticationFailureUrl must be specified",
expected.getMessage());
}
config.setInitParmeter("authenticationFailureUrl", "");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("authenticationFailureUrl must be specified",
expected.getMessage());
}
}
public void testStartupDetectsMissingDefaultTargetUrl()
public void testStartupDetectsInvalidAuthenticationManager()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationFailureUrl("/failed.jsp");
filter.setDefaultTargetUrl("/");
filter.setFilterProcessesUrl("/j_acegi_security_check");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("defaultTargetUrl must be specified",
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("authenticationManager must be specified",
expected.getMessage());
}
}
config.setInitParmeter("defaultTargetUrl", "");
public void testStartupDetectsInvalidDefaultTargetUrl()
throws Exception {
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationFailureUrl("/failed.jsp");
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setFilterProcessesUrl("/j_acegi_security_check");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("defaultTargetUrl must be specified",
expected.getMessage());
}
}
public void testStartupDetectsMissingInvalidcontextConfigLocation()
public void testStartupDetectsInvalidFilterProcessesUrl()
throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
config.setInitParmeter("contextConfigLocation", "DOES_NOT_EXIST");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationFailureUrl("/failed.jsp");
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setDefaultTargetUrl("/");
filter.setFilterProcessesUrl(null);
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertTrue(expected.getMessage().startsWith("Cannot locate"));
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("filterProcessesUrl must be specified",
expected.getMessage());
}
}
@@ -395,19 +371,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"koala");
request.setServletPath("/j_acegi_security_check");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will not be invoked, as we redirect to authenticationFailureUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/", response.getRedirect());
@@ -440,19 +417,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
request.getSession().setAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY,
"/my-destination");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) ctx
.getBean("authenticationProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-valid.xml");
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/my-destination", response.getRedirect());
@@ -47,4 +47,11 @@
</property>
</bean>
<bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="authenticationFailureUrl"><value>/failed.jsp</value></property>
<property name="defaultTargetUrl"><value>/</value></property>
<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
</bean>
</beans>
@@ -0,0 +1,260 @@
/* Copyright 2004 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 net.sf.acegisecurity.util;
import junit.framework.TestCase;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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;
/**
* Tests {@link FilterToBeanProxy}.
*
* @author Ben Alex
* @version $Id$
*/
public class FilterToBeanProxyTests extends TestCase {
//~ Constructors ===========================================================
public FilterToBeanProxyTests() {
super();
}
public FilterToBeanProxyTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(FilterToBeanProxyTests.class);
}
public void testDetectsClassNotInClassLoader() throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass", "net.sf.DOES.NOT.EXIST");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Class of type net.sf.DOES.NOT.EXIST not found in classloader",
expected.getMessage());
}
}
public void testDetectsMissingTargetClass() throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetBean", "mockFilter");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("targetClass must be specified", expected.getMessage());
}
}
public void testDetectsTargetBeanIsNotAFilter() throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass",
"net.sf.acegisecurity.util.MockNotAFilter");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Bean 'mockNotAFilter' does not implement javax.servlet.Filter",
expected.getMessage());
}
}
public void testDetectsTargetBeanNotInBeanContext()
throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass",
"net.sf.acegisecurity.util.MockFilter");
config.setInitParmeter("targetBean", "WRONG_NAME");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Bean with name 'WRONG_NAME' cannot be found in bean context",
expected.getMessage());
}
}
public void testDetectsTargetClassNotInBeanContext()
throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass",
"net.sf.acegisecurity.util.FilterToBeanProxyTests");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Bean context must contain at least one bean of type net.sf.acegisecurity.util.FilterToBeanProxyTests",
expected.getMessage());
}
}
public void testIgnoresEmptyTargetBean() throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass",
"net.sf.acegisecurity.util.MockFilter");
config.setInitParmeter("targetBean", "");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest("/go");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
executeFilterInContainerSimulator(config, filter, request, response,
chain);
}
public void testNormalOperationWithDefault() throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass",
"net.sf.acegisecurity.util.MockFilter");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest("/go");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
executeFilterInContainerSimulator(config, filter, request, response,
chain);
}
public void testNormalOperationWithSpecificBeanName()
throws Exception {
// Setup our filter
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("targetClass",
"net.sf.acegisecurity.util.MockFilter");
config.setInitParmeter("targetBean", "mockFilter");
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest("/go");
FilterToBeanProxy filter = new MockFilterToBeanProxy(
"net/sf/acegisecurity/util/filtertest-valid.xml");
executeFilterInContainerSimulator(config, filter, request, response,
chain);
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig,
Filter filter, ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
//~ Inner Classes ==========================================================
private class MockFilterChain implements FilterChain {
private boolean expectToProceed;
public MockFilterChain(boolean expectToProceed) {
this.expectToProceed = expectToProceed;
}
private MockFilterChain() {
super();
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (expectToProceed) {
assertTrue(true);
} else {
fail("Did not expect filter chain to proceed");
}
}
}
private class MockFilterToBeanProxy extends FilterToBeanProxy {
private String appContextLocation;
public MockFilterToBeanProxy(String appContextLocation) {
this.appContextLocation = appContextLocation;
}
private MockFilterToBeanProxy() {
super();
}
protected ApplicationContext getContext(FilterConfig filterConfig) {
return new ClassPathXmlApplicationContext(appContextLocation);
}
}
}
@@ -0,0 +1,45 @@
/* Copyright 2004 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 net.sf.acegisecurity.util;
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;
/**
* A simple filter that the test case can delegate to.
*
* @author Ben Alex
* @version $Id$
*/
public class MockFilter implements Filter {
//~ Methods ================================================================
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {}
}
@@ -0,0 +1,24 @@
/* Copyright 2004 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 net.sf.acegisecurity.util;
/**
* A class that is not a filter.
*
* @author Ben Alex
* @version $Id$
*/
public class MockNotAFilter {}
@@ -21,17 +21,7 @@
<beans>
<bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
dianne=emu,ROLE_TELLER
scott=wombat,ROLE_TELLER
peter=opal,disabled,ROLE_TELLER
</value>
</property>
</bean>
<!-- FilterSecurityInterceptor deliberately missing to cause error -->
<bean id="mockFilter" class="net.sf.acegisecurity.util.MockFilter"/>
<bean id="mockNotAFilter" class="net.sf.acegisecurity.util.MockNotAFilter"/>
</beans>