change AuthenticationProcessingFilter and SecurityEnforcementFilter to use Spring's WebApplicationContextUtils by defualt to find their config context.

This commit is contained in:
Colin Sampaleanu
2004-04-09 02:44:17 +00:00
parent 7bb4f14849
commit 6c26e79a0f
9 changed files with 185 additions and 66 deletions

View File

@@ -21,7 +21,7 @@ import org.springframework.core.NestedRuntimeException;
/**
* Abstract superclass for all exceptions thrown in the security package and
* subpackages.
*
*
* <p>
* Note that this is a runtime (unchecked) exception. Security exceptions are
* usually fatal; there is no reason for them to be checked.

View File

@@ -22,8 +22,12 @@ import net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException;
import java.util.Map;
@@ -41,12 +45,12 @@ import javax.servlet.http.HttpServletResponse;
/**
* Wraps requests to the {@link FilterSecurityInterceptor}.
*
* <P>
* This filter is necessary because it provides an application context
* environment for the <code>FilterSecurityInterceptor</code> instance.
* <p>
* This filter is necessary because it provides the bridge between incoming
* requests and the <code>FilterSecurityInterceptor</code> instance.
* </p>
*
* <P>
* <p>
* If a {@link AuthenticationException} is detected, the filter will redirect
* to the <code>loginFormUrl</code>. This allows common handling of
* authentication failures originating from any subclass of {@link
@@ -60,33 +64,55 @@ import javax.servlet.http.HttpServletResponse;
* security interceptor.
* </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
* initialization parameters:
* </p>
*
* <ul>
* <li>
* <code>appContextLocation</code> indicates the path to an application context
* that contains the <code>FilterSecurityInterceptor</code>.
* </li>
* <li>
* <code>loginFormUrl</code> indicates the URL that should be used for
* redirection if an <code>AuthenticationException</code> is detected.
* </li>
* <li>
* <code>contextConfigLocation</code> (optional, normally not used), indicates
* the path to an application context that contains a properly configured
* <code>FilterSecurityInterceptor</code>. If not specified, {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* will be used to obtain the context.
* </li>
* </ul>
* </p>
*
*
* @author Ben Alex
* @author colin sampaleanu
* @version $Id$
*/
public class SecurityEnforcementFilter implements Filter {
//~ Static fields/initializers =============================================
/**
* Name of (optional) servlet filter parameter that can specify the config
* location for a new ApplicationContext used to config this filter.
*/
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
private static final Log logger = LogFactory.getLog(SecurityEnforcementFilter.class);
//~ Instance fields ========================================================
protected ClassPathXmlApplicationContext ctx;
protected FilterSecurityInterceptor securityInterceptor;
/**
@@ -94,11 +120,15 @@ public class SecurityEnforcementFilter implements Filter {
* <code>AuthenticationException</code> is detected.
*/
protected String loginFormUrl;
private ApplicationContext ctx;
private boolean ourContext = false;
//~ Methods ================================================================
public void destroy() {
ctx.close();
if (ourContext && ctx instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) ctx).close();
}
}
public void doFilter(ServletRequest request, ServletResponse response,
@@ -145,15 +175,15 @@ public class SecurityEnforcementFilter implements Filter {
}
public void init(FilterConfig filterConfig) throws ServletException {
String appContextLocation = filterConfig.getInitParameter(
"appContextLocation");
String appContextLocation = filterConfig.getInitParameter(CONFIG_LOCATION_PARAM);
if ((appContextLocation == null) || "".equals(appContextLocation)) {
throw new ServletException("appContextLocation must be specified");
}
if ((appContextLocation != null) && (appContextLocation.length() > 0)) {
ourContext = true;
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate " + appContextLocation);
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate "
+ appContextLocation);
}
}
loginFormUrl = filterConfig.getInitParameter("loginFormUrl");
@@ -162,7 +192,21 @@ public class SecurityEnforcementFilter implements Filter {
throw new ServletException("loginFormUrl must be specified");
}
ctx = new ClassPathXmlApplicationContext(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(FilterSecurityInterceptor.class, true,
true);

View File

@@ -23,8 +23,12 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException;
import java.util.Map;
@@ -52,30 +56,39 @@ import javax.servlet.http.HttpServletResponse;
* HttpSessionIntegrationFilter#ACEGI_SECURITY_AUTHENTICATION_KEY}.
* </p>
*
* <P>
* <p>
* Login forms must present two parameters to this filter: a username and
* password. The filter will process the login against the authentication
* environment that was configured from a Spring application context defined
* in the filter initialization.
* </p>
*
* <P>
* <p>
* If authentication fails, the <code>AuthenticationException</code> will be
* placed into the <code>HttpSession</code> with the attribute defined by
* {@link #ACEGI_SECURITY_LAST_EXCEPTION_KEY}.
* </p>
*
* <P>
* <p>
* This filter works with an {@link AuthenticationManager} which is used to
* process each authentication request. By default, at init time, the filter
* will use Spring's {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* method to obtain an ApplicationContext instance, inside which must be a
* configured AuthenticationManager instance. In the case where it is
* desireable 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>appContextLocation</code> init param.
* </p>
*
* <p>
* To use this filter, it is necessary to specify the following filter
* initialization parameters:
* </p>
*
* <ul>
* <li>
* <code>appContextLocation</code> indicates the path to an application context
* that contains an {@link AuthenticationManager} that should be used to
* process each authentication request.
* </li>
* <li>
* <code>defaultTargetUrl</code> indicates the URL that should be used for
* redirection if the <code>HttpSession</code> attribute named {@link
* #ACEGI_SECURITY_TARGET_URL_KEY} does not indicate the target URL once
@@ -91,15 +104,29 @@ import javax.servlet.http.HttpServletResponse;
* respond to. This parameter is optional, and defaults to
* <code>/j_acegi_security_check</code>.
* </li>
* <li>
* <code>appContextLocation</code> (optional, normally not used), indicates the
* path to an application context that contains an {@link
* AuthenticationManager} which should be used to process each authentication
* request. If not specified, {@link
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
* will be used to obtain the context.
* </li>
* </ul>
* </p>
*
*
* @author Ben Alex
* @author colin sampaleanu
* @version $Id$
*/
public class AuthenticationProcessingFilter implements Filter {
//~ 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 = "appContextLocation";
public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL";
public static final String ACEGI_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password";
@@ -108,8 +135,8 @@ public class AuthenticationProcessingFilter implements Filter {
//~ Instance fields ========================================================
private ApplicationContext ctx;
private AuthenticationManager authenticationManager;
private ClassPathXmlApplicationContext ctx;
/** Where to redirect the browser to if authentication fails */
private String authenticationFailureUrl;
@@ -125,11 +152,14 @@ public class AuthenticationProcessingFilter implements Filter {
* <code>/j_acegi_security_check</code>)
*/
private String filterProcessesUrl;
private boolean ourContext = false;
//~ Methods ================================================================
public void destroy() {
ctx.close();
if (ourContext && ctx instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) ctx).close();
}
}
public void doFilter(ServletRequest request, ServletResponse response,
@@ -216,15 +246,15 @@ public class AuthenticationProcessingFilter implements Filter {
}
public void init(FilterConfig filterConfig) throws ServletException {
String appContextLocation = filterConfig.getInitParameter(
"appContextLocation");
String appContextLocation = filterConfig.getInitParameter(CONFIG_LOCATION_PARAM);
if ((appContextLocation == null) || "".equals(appContextLocation)) {
throw new ServletException("appContextLocation must be specified");
}
if ((appContextLocation != null) && (appContextLocation.length() > 0)) {
ourContext = true;
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate " + appContextLocation);
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
throw new ServletException("Cannot locate "
+ appContextLocation);
}
}
defaultTargetUrl = filterConfig.getInitParameter("defaultTargetUrl");
@@ -248,7 +278,21 @@ public class AuthenticationProcessingFilter implements Filter {
filterProcessesUrl = "/j_acegi_security_check";
}
ctx = new ClassPathXmlApplicationContext(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);