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