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/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/> <include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/> <include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/> <include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/> <include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/catalina/*"/> <include name="net/sf/acegisecurity/adapters/catalina/*"/>
@ -202,6 +203,7 @@
<include name="net/sf/acegisecurity/runas/**"/> <include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/> <include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/> <include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/> <include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/> <include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/jetty/*"/> <include name="net/sf/acegisecurity/adapters/jetty/*"/>
@ -221,6 +223,7 @@
<include name="net/sf/acegisecurity/runas/**"/> <include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/> <include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/> <include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/> <include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/> <include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/jboss/*"/> <include name="net/sf/acegisecurity/adapters/jboss/*"/>
@ -240,6 +243,7 @@
<include name="net/sf/acegisecurity/runas/**"/> <include name="net/sf/acegisecurity/runas/**"/>
<include name="net/sf/acegisecurity/vote/**"/> <include name="net/sf/acegisecurity/vote/**"/>
<include name="net/sf/acegisecurity/ui/**"/> <include name="net/sf/acegisecurity/ui/**"/>
<include name="net/sf/acegisecurity/util/**"/>
<include name="net/sf/acegisecurity/intercept/**"/> <include name="net/sf/acegisecurity/intercept/**"/>
<include name="net/sf/acegisecurity/adapters/*"/> <include name="net/sf/acegisecurity/adapters/*"/>
<include name="net/sf/acegisecurity/adapters/resin/*"/> <include name="net/sf/acegisecurity/adapters/resin/*"/>
@ -258,7 +262,6 @@
<zip zipfile="${dist.dir}/${acegi-security-src.zip}"> <zip zipfile="${dist.dir}/${acegi-security-src.zip}">
<fileset dir="${src.dir}"> <fileset dir="${src.dir}">
<include name="net/sf/acegisecurity/**"/> <include name="net/sf/acegisecurity/**"/>
<include name="net/sf/acegisecurity/context/**"/>
</fileset> </fileset>
</zip> </zip>
</target> </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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
@ -65,72 +59,79 @@ import javax.servlet.http.HttpServletResponse;
* </p> * </p>
* *
* <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 * To use this filter, it is necessary to specify the following filter
* initialization parameters: * initialization parameters:
* </p> * </p>
* *
* <ul> * <ul>
* <li> * <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 * <code>loginFormUrl</code> indicates the URL that should be used for
* redirection if an <code>AuthenticationException</code> is detected. * redirection if an <code>AuthenticationException</code> is detected.
* </li> * </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> * </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 Ben Alex
* @author colin sampaleanu * @author colin sampaleanu
* @version $Id$ * @version $Id$
*/ */
public class SecurityEnforcementFilter implements Filter { public class SecurityEnforcementFilter implements Filter, InitializingBean {
//~ Static fields/initializers ============================================= //~ 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); private static final Log logger = LogFactory.getLog(SecurityEnforcementFilter.class);
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected FilterSecurityInterceptor securityInterceptor; protected FilterSecurityInterceptor filterSecurityInterceptor;
/** /**
* The URL that should be used for redirection if an * The URL that should be used for redirection if an
* <code>AuthenticationException</code> is detected. * <code>AuthenticationException</code> is detected.
*/ */
protected String loginFormUrl; protected String loginFormUrl;
private ApplicationContext ctx;
private boolean ourContext = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void destroy() { public void setFilterSecurityInterceptor(
if (ourContext && ctx instanceof ConfigurableApplicationContext) { FilterSecurityInterceptor filterSecurityInterceptor) {
((ConfigurableApplicationContext) ctx).close(); 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, public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) { if (!(request instanceof HttpServletRequest)) {
@ -144,7 +145,7 @@ public class SecurityEnforcementFilter implements Filter {
FilterInvocation fi = new FilterInvocation(request, response, chain); FilterInvocation fi = new FilterInvocation(request, response, chain);
try { try {
securityInterceptor.invoke(fi); filterSecurityInterceptor.invoke(fi);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Chain processed normally"); logger.debug("Chain processed normally");
@ -174,49 +175,5 @@ public class SecurityEnforcementFilter implements Filter {
} }
} }
public void init(FilterConfig filterConfig) throws ServletException { 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);
}
} }

View File

@ -25,16 +25,10 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; 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>". * sent with a request, it should return a 403 (forbidden) response.</I>".
* </p> * </p>
* *
* <p> * <P>
* This filter works with an {@link AuthenticationManager} which is used to * <B>Do not use this class directly.</B> Instead configure
* process each authentication request. By default, at init time, the filter * <code>web.xml</code> to use the {@link
* will use Spring's {@link * net.sf.acegisecurity.util.FilterToBeanProxy}.
* 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>
* *
* <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 * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class BasicProcessingFilter implements Filter { public class BasicProcessingFilter implements Filter, InitializingBean {
//~ Static fields/initializers ============================================= //~ 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); private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private ApplicationContext ctx;
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
private boolean ourContext = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void destroy() { public void setAuthenticationManager(
if (ourContext && ctx instanceof ConfigurableApplicationContext) { AuthenticationManager authenticationManager) {
((ConfigurableApplicationContext) ctx).close(); 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, public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) { if (!(request instanceof HttpServletRequest)) {
@ -208,42 +183,5 @@ public class BasicProcessingFilter implements Filter {
chain.doFilter(request, response); chain.doFilter(request, response);
} }
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig arg0) 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);
}
} }

View File

@ -23,16 +23,10 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
@ -70,21 +64,7 @@ import javax.servlet.http.HttpServletResponse;
* </p> * </p>
* *
* <p> * <p>
* This filter works with an {@link AuthenticationManager} which is used to * To use this filter, it is necessary to specify the following properties:
* 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:
* </p> * </p>
* *
* <ul> * <ul>
@ -104,29 +84,21 @@ import javax.servlet.http.HttpServletResponse;
* respond to. This parameter is optional, and defaults to * respond to. This parameter is optional, and defaults to
* <code>/j_acegi_security_check</code>. * <code>/j_acegi_security_check</code>.
* </li> * </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> * </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 Ben Alex
* @author Colin Sampaleanu * @author Colin Sampaleanu
* @version $Id$ * @version $Id$
*/ */
public class AuthenticationProcessingFilter implements Filter { public class AuthenticationProcessingFilter implements Filter, InitializingBean {
//~ Static fields/initializers ============================================= //~ 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_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_USERNAME_KEY = "j_username";
public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password"; public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password";
@ -135,7 +107,6 @@ public class AuthenticationProcessingFilter implements Filter {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private ApplicationContext ctx;
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
/** Where to redirect the browser to if authentication fails */ /** 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 * The URL destination that this filter intercepts and processes (usually
* <code>/j_acegi_security_check</code>) * <code>/j_acegi_security_check</code>)
*/ */
private String filterProcessesUrl; private String filterProcessesUrl = "/j_acegi_security_check";
private boolean ourContext = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void destroy() { public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
if (ourContext && ctx instanceof ConfigurableApplicationContext) { this.authenticationFailureUrl = authenticationFailureUrl;
((ConfigurableApplicationContext) ctx).close(); }
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, public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) { if (!(request instanceof HttpServletRequest)) {
@ -245,63 +267,5 @@ public class AuthenticationProcessingFilter implements Filter {
chain.doFilter(request, response); chain.doFilter(request, response);
} }
public void init(FilterConfig filterConfig) throws ServletException { 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);
}
} }

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.AccessDeniedException;
import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest; import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse; import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.MockHttpSession; import net.sf.acegisecurity.MockHttpSession;
@ -75,9 +74,11 @@ public class SecurityEnforcementFilterTests extends TestCase {
false); false);
// Test // Test
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(interceptor);
filter.setLoginFormUrl("/login.jsp");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
SecurityEnforcementFilter filter = new MockSecurityEnforcementFilter(interceptor,
"/login.jsp");
filter.doFilter(request, response, chain); filter.doFilter(request, response, chain);
assertEquals(403, response.getError()); 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() public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWhenAuthenticationException()
throws Exception { throws Exception {
// Setup our HTTP request // Setup our HTTP request
@ -123,93 +134,42 @@ public class SecurityEnforcementFilterTests extends TestCase {
true); true);
// Test // Test
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(interceptor);
filter.setLoginFormUrl("/login.jsp");
filter.afterPropertiesSet();
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
SecurityEnforcementFilter filter = new MockSecurityEnforcementFilter(interceptor,
"/login.jsp");
filter.doFilter(request, response, chain); filter.doFilter(request, response, chain);
assertEquals("/login.jsp", response.getRedirect()); assertEquals("/login.jsp", response.getRedirect());
assertEquals("/secure/page.html", assertEquals("/secure/page.html",
request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY));
} }
public void testStartupDetectsInvalidcontextConfigLocation() public void testStartupDetectsMissingFilterSecurityInterceptor()
throws Exception { 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(); SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setLoginFormUrl("/login.jsp");
try { try {
filter.init(config); filter.afterPropertiesSet();
fail("Should have thrown ServletException"); fail("Should have thrown IllegalArgumentException");
} catch (ServletException expected) { } catch (IllegalArgumentException expected) {
assertEquals("Bean context must contain at least one bean of type FilterSecurityInterceptor", assertEquals("filterSecurityInterceptor must be specified",
expected.getMessage()); 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() public void testStartupDetectsMissingLoginFormUrl()
throws Exception { throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/intercept/web/securityfiltertest-valid.xml");
SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
false, false));
try { try {
filter.init(config); filter.afterPropertiesSet();
fail("Should have thrown ServletException"); fail("Should have thrown IllegalArgumentException");
} catch (ServletException expected) { } catch (IllegalArgumentException expected) {
assertEquals("loginFormUrl must be specified", expected.getMessage());
}
config.setInitParmeter("loginFormUrl", "");
try {
filter.init(config);
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("loginFormUrl must be specified", expected.getMessage()); assertEquals("loginFormUrl must be specified", expected.getMessage());
} }
} }
@ -228,22 +188,19 @@ public class SecurityEnforcementFilterTests extends TestCase {
false); false);
// Test // Test
SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.setFilterSecurityInterceptor(interceptor);
filter.setLoginFormUrl("/login.jsp");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
SecurityEnforcementFilter filter = new MockSecurityEnforcementFilter(interceptor,
"/login.jsp");
filter.doFilter(request, response, chain); filter.doFilter(request, response, chain);
} }
public void testSuccessfulStartupAndShutdownDown() public void testSuccessfulStartupAndShutdownDown()
throws Exception { 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(); SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
filter.init(config); filter.init(null);
filter.destroy(); filter.destroy();
assertTrue(true); assertTrue(true);
} }
@ -298,17 +255,4 @@ public class SecurityEnforcementFilterTests extends TestCase {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); 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 junit.framework.TestCase;
import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.MockAuthenticationManager;
import net.sf.acegisecurity.MockFilterConfig; import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest; import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse; 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.apache.commons.codec.binary.Base64;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@ -102,23 +106,32 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession()); null, new MockHttpSession());
request.setServletPath("/some_file.html"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null); 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() public void testInvalidBasicAuthorizationTokenIsIgnored()
throws Exception { throws Exception {
// Setup our HTTP request // Setup our HTTP request
@ -131,17 +144,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession()); null, new MockHttpSession());
request.setServletPath("/some_file.html"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
@ -159,17 +175,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession()); null, new MockHttpSession());
request.setServletPath("/some_file.html"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
@ -189,77 +208,38 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession()); null, new MockHttpSession());
request.setServletPath("/some_file.html"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null); assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
} }
public void testStartupDetectsInvalidContextConfigLocation() public void testStartupDetectsMissingAuthenticationManager()
throws Exception { throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("contextConfigLocation",
"net/sf/acegisecurity/ui/webapp/filtertest-invalid.xml");
BasicProcessingFilter filter = new BasicProcessingFilter();
try { try {
filter.init(config); BasicProcessingFilter filter = new BasicProcessingFilter();
fail("Should have thrown ServletException"); filter.afterPropertiesSet();
} catch (ServletException expected) { fail("Should have thrown IllegalArgumentException");
assertEquals("Bean context must contain at least one bean of type AuthenticationManager", } catch (IllegalArgumentException expected) {
assertEquals("An AuthenticationManager is required",
expected.getMessage()); 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() public void testSuccessLoginThenFailureLoginResultsInSessionLoosingToken()
throws Exception { throws Exception {
// Setup our HTTP request // Setup our HTTP request
@ -272,17 +252,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession()); null, new MockHttpSession());
request.setServletPath("/some_file.html"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
@ -306,7 +289,6 @@ public class BasicProcessingFilterTests extends TestCase {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
// Test // Test
filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
@ -325,17 +307,20 @@ public class BasicProcessingFilterTests extends TestCase {
null, new MockHttpSession()); null, new MockHttpSession());
request.setServletPath("/some_file.html"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we get a 403 forbidden response
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
BasicProcessingFilter filter = new BasicProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);

View File

@ -33,6 +33,22 @@
</property> </property>
</bean> </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> </beans>

View File

@ -18,11 +18,15 @@ package net.sf.acegisecurity.ui.webapp;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.MockAuthenticationManager;
import net.sf.acegisecurity.MockFilterConfig; import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest; import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse; import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.MockHttpSession; import net.sf.acegisecurity.MockHttpSession;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException; import java.io.IOException;
import javax.servlet.Filter; import javax.servlet.Filter;
@ -100,19 +104,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"WRONG_PASSWORD"); "WRONG_PASSWORD");
request.setServletPath("/j_acegi_security_check"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to authenticationFailureUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
System.out.println(response.getRedirect()); System.out.println(response.getRedirect());
@ -129,22 +134,25 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"marissa"); "marissa");
request.setParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, request.setParameter(AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY,
"koala"); "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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertEquals("/", response.getRedirect()); assertEquals("/", response.getRedirect());
@ -154,6 +162,21 @@ public class AuthenticationProcessingFilterTests extends TestCase {
.toString()); .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() public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl()
throws Exception { throws Exception {
// Setup our HTTP request // Setup our HTTP request
@ -161,18 +184,19 @@ public class AuthenticationProcessingFilterTests extends TestCase {
new MockHttpSession()); new MockHttpSession());
request.setServletPath("/j_some_other_url"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will be invoked, as should just proceed with chain
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, executeFilterInContainerSimulator(config, filter, request,
new MockHttpServletResponse(), chain); new MockHttpServletResponse(), chain);
} }
@ -188,19 +212,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"koala"); "koala");
request.setServletPath("/j_acegi_security_check"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertEquals("/", response.getRedirect()); assertEquals("/", response.getRedirect());
@ -220,19 +245,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
null); null);
request.setServletPath("/j_acegi_security_check"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertEquals("/failed.jsp", response.getRedirect()); assertEquals("/failed.jsp", response.getRedirect());
@ -249,138 +275,88 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"koala"); "koala");
request.setServletPath("/j_acegi_security_check"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertEquals("/failed.jsp", response.getRedirect()); assertEquals("/failed.jsp", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null); assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
} }
public void testStartupDetectsInvalidcontextConfigLocation() public void testStartupDetectsInvalidAuthenticationFailureUrl()
throws Exception { 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(); AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setDefaultTargetUrl("/");
filter.setFilterProcessesUrl("/j_acegi_security_check");
try { try {
filter.init(config); filter.afterPropertiesSet();
fail("Should have thrown ServletException"); fail("Should have thrown IllegalArgumentException");
} catch (ServletException expected) { } catch (IllegalArgumentException 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) {
assertEquals("authenticationFailureUrl must be specified", assertEquals("authenticationFailureUrl must be specified",
expected.getMessage()); expected.getMessage());
} }
} }
public void testStartupDetectsMissingDefaultTargetUrl() public void testStartupDetectsInvalidAuthenticationManager()
throws Exception { 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(); AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationFailureUrl("/failed.jsp");
filter.setDefaultTargetUrl("/");
filter.setFilterProcessesUrl("/j_acegi_security_check");
try { try {
filter.init(config); filter.afterPropertiesSet();
fail("Should have thrown ServletException"); fail("Should have thrown IllegalArgumentException");
} catch (ServletException expected) { } catch (IllegalArgumentException expected) {
assertEquals("defaultTargetUrl must be specified", assertEquals("authenticationManager must be specified",
expected.getMessage()); 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 { try {
filter.init(config); filter.afterPropertiesSet();
fail("Should have thrown ServletException"); fail("Should have thrown IllegalArgumentException");
} catch (ServletException expected) { } catch (IllegalArgumentException expected) {
assertEquals("defaultTargetUrl must be specified", assertEquals("defaultTargetUrl must be specified",
expected.getMessage()); expected.getMessage());
} }
} }
public void testStartupDetectsMissingInvalidcontextConfigLocation() public void testStartupDetectsInvalidFilterProcessesUrl()
throws Exception { throws Exception {
MockFilterConfig config = new MockFilterConfig();
config.setInitParmeter("defaultTargetUrl", "/");
config.setInitParmeter("authenticationFailureUrl", "/failed.jsp");
config.setInitParmeter("contextConfigLocation", "DOES_NOT_EXIST");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter(); AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationFailureUrl("/failed.jsp");
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setDefaultTargetUrl("/");
filter.setFilterProcessesUrl(null);
try { try {
filter.init(config); filter.afterPropertiesSet();
fail("Should have thrown ServletException"); fail("Should have thrown IllegalArgumentException");
} catch (ServletException expected) { } catch (IllegalArgumentException expected) {
assertTrue(expected.getMessage().startsWith("Cannot locate")); assertEquals("filterProcessesUrl must be specified",
expected.getMessage());
} }
} }
@ -395,19 +371,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
"koala"); "koala");
request.setServletPath("/j_acegi_security_check"); 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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to authenticationFailureUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertEquals("/", response.getRedirect()); assertEquals("/", response.getRedirect());
@ -440,19 +417,20 @@ public class AuthenticationProcessingFilterTests extends TestCase {
request.getSession().setAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY, request.getSession().setAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY,
"/my-destination"); "/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 // Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(); 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 // Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false); MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
// Test // Test
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
executeFilterInContainerSimulator(config, filter, request, response, executeFilterInContainerSimulator(config, filter, request, response,
chain); chain);
assertEquals("/my-destination", response.getRedirect()); assertEquals("/my-destination", response.getRedirect());

View File

@ -47,4 +47,11 @@
</property> </property>
</bean> </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> </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> <beans>
<bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"> <bean id="mockFilter" class="net.sf.acegisecurity.util.MockFilter"/>
<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="mockNotAFilter" class="net.sf.acegisecurity.util.MockNotAFilter"/>
</beans> </beans>

View File

@ -503,14 +503,14 @@
<title>FilterInvocation Security Interceptor</title> <title>FilterInvocation Security Interceptor</title>
<para>To secure <literal>FilterInvocation</literal>s, developers need <para>To secure <literal>FilterInvocation</literal>s, developers need
to add a <literal>SecurityEnforcementFilter</literal> to their to add a filter to their <literal>web.xml</literal> that delegates to
<literal>web.xml</literal>. A typical configuration example is the <literal>SecurityEnforcementFilter</literal>. A typical
provided below: <programlisting>&lt;filter&gt; configuration example is provided below: <programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&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;init-param&gt;
&lt;param-name&gt;loginFormUrl&lt;/param-name&gt; &lt;param-name&gt;targetClass&lt;/param-name&gt;
&lt;param-value&gt;/acegilogin.jsp&lt;/param-value&gt; &lt;param-value&gt;net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter&lt;/param-value&gt;
&lt;/init-param&gt; &lt;/init-param&gt;
&lt;/filter&gt; &lt;/filter&gt;
@ -519,34 +519,36 @@
&lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para> &lt;/filter-mapping&gt;</programlisting></para>
<para>The <literal>loginFormUrl</literal> is where the filter will <para>Notice that the filter is actually a
redirect the user's browser if they request a secure HTTP resource but <literal>FilterToBeanProxy</literal>. Most of the filters used by the
they are not authenticated. If the user is authenticated, a "403 Acegi Security System for Spring use this class . What it does is
Forbidden" response will be returned to the browser. All paths are delegate the <literal>Filter</literal>'s methods through to a bean
relative to the web application root.</para> 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 <para>In the application context you will need to configure two
<literal>SecurityEnforcementFilter</literal> will need to delegate to beans:</para>
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>The configuration of the <programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
<literal>FilterSecurityInterceptor</literal> in the Spring application &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
context is very similar to the &lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
<literal>MethodSecurityInterceptor</literal>:</para> &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="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="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
&lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&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 \A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
&lt;/value&gt; &lt;/value&gt;
&lt;/property&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 <para>Like any other security interceptor, the
<literal>FilterSecurityInterceptor</literal> requires a reference to <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 <literal>j_password</literal> input fields, and posts to a URL that is
monitored by the filter (by default monitored by the filter (by default
<literal>j_acegi_security_check</literal>). The filter is defined in <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; <para><programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&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;init-param&gt;
&lt;param-name&gt;authenticationFailureUrl&lt;/param-name&gt; &lt;param-name&gt;targetClass&lt;/param-name&gt;
&lt;param-value&gt;/acegilogin.jsp?login_error=1&lt;/param-value&gt; &lt;param-value&gt;net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter&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;/init-param&gt; &lt;/init-param&gt;
&lt;/filter&gt; &lt;/filter&gt;
@ -1507,25 +1513,22 @@ public boolean supports(Class clazz);</programlisting></para>
&lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para> &lt;/filter-mapping&gt;</programlisting></para>
<para>To perform its function, the <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
<literal>AuthenticationProcessingFilter</literal> will need to refer to the FilterInvocation Security Interceptor section. The
delegate to a properly configured application context will need to define the
<literal>AuthenticationManager</literal>. To do this it requires <literal>AuthenticationProcessingFilter</literal>:</para>
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>The <literal>AuthenticationManager</literal> processes each <para><programlisting>&lt;bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;
authentication request. If authentication fails, the browser will be &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
redirected to the <literal>authenticationFailureUrl</literal>. The &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>AuthenticationException</literal> will be placed into the
<literal>HttpSession</literal> attribute indicated by <literal>HttpSession</literal> attribute indicated by
<literal>AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY</literal>, <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. is completed the user can return to what they were trying to access.
If for some reason the <literal>HttpSession</literal> does not If for some reason the <literal>HttpSession</literal> does not
indicate the target URL, the browser will be redirected to the indicate the target URL, the browser will be redirected to the
<literal>defaultTargetUrl</literal> filter initialization <literal>defaultTargetUrl</literal> property.</para>
property.</para>
<para>Because this authentication approach is fully contained within a <para>Because this authentication approach is fully contained within a
single web application, HTTP Session Authentication is recommended to 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 standard authentication of web browser users, we recommend HTTP
Session Authentication). The standard governing HTTP Basic Session Authentication). The standard governing HTTP Basic
Authentication is defined by RFC 1945, Section 11, and the Authentication is defined by RFC 1945, Section 11, and the
<literal>BasicProcessingFilter</literal> conforms with this RFC. To <literal>BasicProcessingFilter</literal> conforms with this RFC.
implement HTTP Basic Authentication, it is necessary to add the </para>
following filter to <literal>web.xml</literal>:</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; <para><programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi HTTP BASIC Authorization Filter&lt;/filter-name&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&gt;
&lt;filter-mapping&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;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para> &lt;/filter-mapping&gt;</programlisting></para>
<para>Like the <literal>AuthenticationProcessingFilter</literal> <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
discussed above, the <literal>BasicProcessingFilter</literal> will refer to the FilterInvocation Security Interceptor section. The
need to delegate to a properly configured application context will need to define the
<literal>AuthenticationManager</literal>. To do this it requires <literal>BasicProcessingFilter</literal>:</para>
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>The <literal>AuthenticationManager</literal> processes each <para><programlisting>&lt;bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter"&gt;
authentication request. If authentication fails, a 403 (forbidden) &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
response will be returned in response to the HTTP request. If &lt;/bean&gt;</programlisting></para>
authentication is successful, the resulting
<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>Authentication</literal> object will be placed into the
<literal>HttpSession</literal> attribute indicated by <literal>HttpSession</literal> attribute indicated by
<literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.

View File

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

View File

@ -26,7 +26,11 @@
<filter> <filter>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name> <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>
<filter> <filter>

View File

@ -45,6 +45,10 @@
<property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property> <property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property>
</bean> </bean>
<bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ --> <!-- ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ -->
<!-- An access decision voter that reads ROLE_* configuaration settings --> <!-- An access decision voter that reads ROLE_* configuaration settings -->
@ -125,6 +129,18 @@
<!-- ===================== HTTP REQUEST SECURITY ==================== --> <!-- ===================== 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"> <bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property> <property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters"> <property name="decisionVoters">
@ -134,11 +150,9 @@
</property> </property>
</bean> </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. 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 --> 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"> <bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property> <property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="httpRequestAccessDecisionManager"/></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>
<filter-name>Acegi Authentication Processing Filter</filter-name> <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> <init-param>
<param-name>authenticationFailureUrl</param-name> <param-name>targetClass</param-name>
<param-value>/acegilogin.jsp?login_error=1</param-value> <param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</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>
</init-param> </init-param>
</filter> </filter>
<filter> <filter>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name> <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>
<filter> <filter>
@ -53,10 +49,10 @@
<filter> <filter>
<filter-name>Acegi HTTP Request Security Filter</filter-name> <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> <init-param>
<param-name>loginFormUrl</param-name> <param-name>targetClass</param-name>
<param-value>/acegilogin.jsp</param-value> <param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
</init-param> </init-param>
</filter> </filter>