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

View File

@ -182,6 +182,7 @@
<include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/catalina/*"/>
@ -202,6 +203,7 @@
<include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/jetty/*"/>
@ -221,6 +223,7 @@
<include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/jboss/*"/>
@ -240,6 +243,7 @@
<include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/resin/*"/>
@ -258,7 +262,6 @@
<zip zipfile="${dist.dir}/${acegi-security-src.zip}">
<fileset dir="${src.dir}">
<include name="net/sf/acegisecurity/**"/>
<include name="net/sf/acegisecurity/context/**"/>
</fileset>
</zip>
</target>

View File

@ -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 {}
}

View File

@ -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 {}
}

View File

@ -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 {}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,5 @@
<html>
<body>
General utility classes used throughout the Acegi Security System.
</body>
</html>

View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -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);

View File

@ -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>

View File

@ -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());

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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 {}
}

View File

@ -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 {}

View File

@ -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>

View File

@ -503,14 +503,14 @@
<title>FilterInvocation Security Interceptor</title>
<para>To secure <literal>FilterInvocation</literal>s, developers need
to add a <literal>SecurityEnforcementFilter</literal> to their
<literal>web.xml</literal>. A typical configuration example is
provided below: <programlisting>&lt;filter&gt;
to add a filter to their <literal>web.xml</literal> that delegates to
the <literal>SecurityEnforcementFilter</literal>. A typical
configuration example is provided below: <programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
&lt;filter-class&gt;net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter&lt;/filter-class&gt;
&lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;loginFormUrl&lt;/param-name&gt;
&lt;param-value&gt;/acegilogin.jsp&lt;/param-value&gt;
&lt;param-name&gt;targetClass&lt;/param-name&gt;
&lt;param-value&gt;net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;
@ -519,34 +519,36 @@
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>
<para>The <literal>loginFormUrl</literal> is where the filter will
redirect the user's browser if they request a secure HTTP resource but
they are not authenticated. If the user is authenticated, a "403
Forbidden" response will be returned to the browser. All paths are
relative to the web application root.</para>
<para>Notice that the filter is actually a
<literal>FilterToBeanProxy</literal>. Most of the filters used by the
Acegi Security System for Spring use this class . What it does is
delegate the <literal>Filter</literal>'s methods through to a bean
which is obtained from the Spring application context. This enables
the bean to benefit from the Spring application context lifecycle
support and configuration flexibility. The
<literal>FilterToBeanProxy</literal> only requires a single
initialization parameter, <literal>targetClass</literal>, which will
be used to identify the bean in the application context. In the
unlikely event there is more than one bean in the application context
that matches this class, the <literal>targetBean</literal>
initialization parameter should be used. This parameter simply
represents the name of the bean in the application context. Like
standard Spring web applications, the
<literal>FilterToBeanProxy</literal> accesses the application context
via<literal>
WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>,
so you should configure a <literal>ContextLoaderListener</literal> in
<literal>web.xml</literal>.</para>
<para>To perform its function, the
<literal>SecurityEnforcementFilter</literal> will need to delegate to
a properly configured <literal>FilterSecurityInterceptor</literal>. To
do this it requires access to a Spring application context, which is
usually obtained from
<literal>WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>.
This is usually made available by using Spring's
<literal>ContextLoaderListener</literal> in
<literal>web.xml</literal>. Alternatively, the
<literal>web.xml</literal> can be used to define a filter
<literal>&lt;init-param&gt;</literal> named
<literal>contextConfigLocation</literal>. This initialization
parameter will represent a path to a Spring XML application context
that the <literal>SecurityEnforcementFilter</literal> will load during
startup.</para>
<para>In the application context you will need to configure two
beans:</para>
<para>The configuration of the
<literal>FilterSecurityInterceptor</literal> in the Spring application
context is very similar to the
<literal>MethodSecurityInterceptor</literal>:</para>
<programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
&lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
&lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;
<para><programlisting>&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
&lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
&lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
@ -557,7 +559,18 @@
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
&lt;/bean&gt;</programlisting>
<para>The <literal>loginFormUrl</literal> is where the filter will
redirect the user's browser if they request a secure HTTP resource but
they are not authenticated. If the user is authenticated, a "403
Forbidden" response will be returned to the browser. All paths are
relative to the web application root.</para>
<para>The <literal>SecurityEnforcementFilter</literal> primarily
provides redirection and session management support. It delegates
actual <literal>FilterInvocation</literal> security decisions to the
configured <literal>FilterSecurityInterceptor</literal>.</para>
<para>Like any other security interceptor, the
<literal>FilterSecurityInterceptor</literal> requires a reference to
@ -1483,22 +1496,15 @@ public boolean supports(Class clazz);</programlisting></para>
<literal>j_password</literal> input fields, and posts to a URL that is
monitored by the filter (by default
<literal>j_acegi_security_check</literal>). The filter is defined in
<literal>web.xml</literal> as follows:</para>
<literal>web.xml</literal> behind a
<literal>FilterToBeanProxy</literal> as follows:</para>
<para><programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
&lt;filter-class&gt;net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter&lt;/filter-class&gt;
&lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;authenticationFailureUrl&lt;/param-name&gt;
&lt;param-value&gt;/acegilogin.jsp?login_error=1&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;init-param&gt;
&lt;param-name&gt;defaultTargetUrl&lt;/param-name&gt;
&lt;param-value&gt;/&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;init-param&gt;
&lt;param-name&gt;filterProcessUrl&lt;/param-name&gt;
&lt;param-value&gt;/j_acegi_security_check&lt;/param-value&gt;
&lt;param-name&gt;targetClass&lt;/param-name&gt;
&lt;param-value&gt;net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;
@ -1507,25 +1513,22 @@ public boolean supports(Class clazz);</programlisting></para>
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>
<para>To perform its function, the
<literal>AuthenticationProcessingFilter</literal> will need to
delegate to a properly configured
<literal>AuthenticationManager</literal>. To do this it requires
access to a Spring application context, which is usually obtained from
<literal>WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>.
This is usually made available by using Spring's
<literal>ContextLoaderListener</literal> in
<literal>web.xml</literal>. Alternatively, the
<literal>web.xml</literal> can be used to define a filter
<literal>&lt;init-param&gt;</literal> named
<literal>contextConfigLocation</literal>. This initialization
parameter will represent a path to a Spring XML application context
that the <literal>AuthenticationProcessingFilter</literal> will load
during startup.</para>
<para>For a discussion of <literal>FilterToBeanProxy</literal>, please
refer to the FilterInvocation Security Interceptor section. The
application context will need to define the
<literal>AuthenticationProcessingFilter</literal>:</para>
<para>The <literal>AuthenticationManager</literal> processes each
authentication request. If authentication fails, the browser will be
redirected to the <literal>authenticationFailureUrl</literal>. The
<para><programlisting>&lt;bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;
&lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/acegilogin.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
&lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
&lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
<para>The configured <literal>AuthenticationManager</literal>
processes each authentication request. If authentication fails, the
browser will be redirected to the
<literal>authenticationFailureUrl</literal>. The
<literal>AuthenticationException</literal> will be placed into the
<literal>HttpSession</literal> attribute indicated by
<literal>AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY</literal>,
@ -1549,8 +1552,7 @@ public boolean supports(Class clazz);</programlisting></para>
is completed the user can return to what they were trying to access.
If for some reason the <literal>HttpSession</literal> does not
indicate the target URL, the browser will be redirected to the
<literal>defaultTargetUrl</literal> filter initialization
property.</para>
<literal>defaultTargetUrl</literal> property.</para>
<para>Because this authentication approach is fully contained within a
single web application, HTTP Session Authentication is recommended to
@ -1567,13 +1569,20 @@ public boolean supports(Class clazz);</programlisting></para>
standard authentication of web browser users, we recommend HTTP
Session Authentication). The standard governing HTTP Basic
Authentication is defined by RFC 1945, Section 11, and the
<literal>BasicProcessingFilter</literal> conforms with this RFC. To
implement HTTP Basic Authentication, it is necessary to add the
following filter to <literal>web.xml</literal>:</para>
<literal>BasicProcessingFilter</literal> conforms with this RFC.
</para>
<para>To implement HTTP Basic Authentication, it is necessary to add
the following filter to <literal>web.xml</literal>, behind a
<literal>FilterToBeanProxy</literal>:</para>
<para><programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi HTTP BASIC Authorization Filter&lt;/filter-name&gt;
&lt;filter-class&gt;net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter&lt;/filter-class&gt;
&lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;targetClass&lt;/param-name&gt;
&lt;param-value&gt;net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
@ -1581,26 +1590,19 @@ public boolean supports(Class clazz);</programlisting></para>
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>
<para>Like the <literal>AuthenticationProcessingFilter</literal>
discussed above, the <literal>BasicProcessingFilter</literal> will
need to delegate to a properly configured
<literal>AuthenticationManager</literal>. To do this it requires
access to a Spring application context, which is usually obtained from
<literal>WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>.
This is usually made available by using Spring's
<literal>ContextLoaderListener</literal> in
<literal>web.xml</literal>. Alternatively, the
<literal>web.xml</literal> can be used to define a filter
<literal>&lt;init-param&gt;</literal> named
<literal>contextConfigLocation</literal>. This initialization
parameter will represent a path to a Spring XML application context
that the <literal>AuthenticationProcessingFilter</literal> will load
during startup.</para>
<para>For a discussion of <literal>FilterToBeanProxy</literal>, please
refer to the FilterInvocation Security Interceptor section. The
application context will need to define the
<literal>BasicProcessingFilter</literal>:</para>
<para>The <literal>AuthenticationManager</literal> processes each
authentication request. If authentication fails, a 403 (forbidden)
response will be returned in response to the HTTP request. If
authentication is successful, the resulting
<para><programlisting>&lt;bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter"&gt;
&lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
<para>The configured <literal>AuthenticationManager</literal>
processes each authentication request. If authentication fails, a 403
(forbidden) response will be returned in response to the HTTP request.
If authentication is successful, the resulting
<literal>Authentication</literal> object will be placed into the
<literal>HttpSession</literal> attribute indicated by
<literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.

View File

@ -50,6 +50,10 @@
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
</bean>
<bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->

View File

@ -26,7 +26,11 @@
<filter>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
<filter-class>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</filter-class>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
</init-param>
</filter>
<filter>

View File

@ -45,6 +45,10 @@
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
</bean>
<bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings -->
@ -125,6 +129,18 @@
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
<bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="authenticationFailureUrl"><value>/acegilogin.jsp?login_error=1</value></property>
<property name="defaultTargetUrl"><value>/</value></property>
<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
</bean>
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
</bean>
<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
@ -134,11 +150,9 @@
</property>
</bean>
<!-- The FilterSecurityInterceptor is called by the web.xml-defined SecurityEnforcementFilter.
Note the order that entries are placed against the objectDefinitionSource is critical.
<!-- Note the order that entries are placed against the objectDefinitionSource is critical.
The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL.
Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last -->
<bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="httpRequestAccessDecisionManager"/></property>

View File

@ -1,112 +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$
*
* This file will be copied into WAR's classes directory if NOT using container adapter
-->
<beans>
<!-- ==================== AUTHENTICATION DEFINITIONS =================== -->
<!-- Data access object which stores authentication information -->
<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>
<!-- 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>
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
<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>
<!-- The FilterSecurityInterceptor is called by the web.xml-defined SecurityEnforcementFilter.
Note the order that entries are placed against the objectDefinitionSource is critical.
The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL.
Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last -->
<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>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/secure/super.*\Z=ROLE_WE_DONT_HAVE
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
</value>
</property>
</bean>
<!-- BASIC Regular Expression Syntax (for beginners):
\A means the start of the string (ie the beginning of the URL)
\Z means the end of the string (ie the end of the URL)
. means any single character
* means null or any number of repetitions of the last expression (so .* means zero or more characters)
Some examples:
Expression: \A/my/directory/.*\Z
Would match: /my/directory/
/my/directory/hello.html
Expression: \A/.*\Z
Would match: /hello.html
/
Expression: \A/.*/secret.html\Z
Would match: /some/directory/secret.html
/another/secret.html
Not match: /anothersecret.html (missing required /)
-->
</beans>

View File

@ -26,24 +26,20 @@
<filter>
<filter-name>Acegi Authentication Processing Filter</filter-name>
<filter-class>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</filter-class>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>authenticationFailureUrl</param-name>
<param-value>/acegilogin.jsp?login_error=1</param-value>
</init-param>
<init-param>
<param-name>defaultTargetUrl</param-name>
<param-value>/</param-value>
</init-param>
<init-param>
<param-name>filterProcessUrl</param-name>
<param-value>/j_acegi_security_check</param-value>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
<filter-class>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</filter-class>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
</init-param>
</filter>
<filter>
@ -53,10 +49,10 @@
<filter>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<filter-class>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</filter-class>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>loginFormUrl</param-name>
<param-value>/acegilogin.jsp</param-value>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
</init-param>
</filter>