diff --git a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java b/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java index 712f269b3a..2837b2b043 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java @@ -17,7 +17,7 @@ package net.sf.acegisecurity.intercept.web; import net.sf.acegisecurity.AccessDeniedException; import net.sf.acegisecurity.AuthenticationException; -import net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter; +import net.sf.acegisecurity.ui.AbstractProcessingFilter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -45,8 +45,8 @@ import javax.servlet.http.HttpServletResponse; *

* *

- * If a {@link AuthenticationException} is detected, the filter will redirect - * to the loginFormUrl. This allows common handling of + * If a {@link AuthenticationException} is detected, the filter will launch the + * authenticationEntryPoint. This allows common handling of * authentication failures originating from any subclass of {@link * net.sf.acegisecurity.intercept.AbstractSecurityInterceptor}. *

@@ -156,7 +156,7 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean { + fi.getRequestUrl()); } - ((HttpServletRequest) request).getSession().setAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY, + ((HttpServletRequest) request).getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY, fi.getRequestUrl()); authenticationEntryPoint.commence(request, response); } catch (AccessDeniedException accessDenied) { diff --git a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java new file mode 100644 index 0000000000..df3bf763eb --- /dev/null +++ b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java @@ -0,0 +1,259 @@ +/* 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.ui; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.AuthenticationException; +import net.sf.acegisecurity.AuthenticationManager; +import net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.InitializingBean; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * Abstract processor of HTTP-based authentication requests, which places the + * resulting Authentication object into the + * HttpSession. + * + *

+ * This filter is responsible for processing authentication requests. If + * authentication is successful, the resulting {@link Authentication} object + * will be placed into the HttpSession with the attribute defined + * by {@link HttpSessionIntegrationFilter#ACEGI_SECURITY_AUTHENTICATION_KEY}. + *

+ * + *

+ * If authentication fails, the AuthenticationException will be + * placed into the HttpSession with the attribute defined by + * {@link #ACEGI_SECURITY_LAST_EXCEPTION_KEY}. + *

+ * + *

+ * To use this filter, it is necessary to specify the following properties: + *

+ * + * + * + * + * @author Ben Alex + * @version $Id$ + */ +public abstract class AbstractProcessingFilter implements Filter, + InitializingBean { + //~ Static fields/initializers ============================================= + + public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL"; + public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION"; + protected static final Log logger = LogFactory.getLog(AbstractProcessingFilter.class); + + //~ Instance fields ======================================================== + + private AuthenticationManager authenticationManager; + + /** Where to redirect the browser to if authentication fails */ + private String authenticationFailureUrl; + + /** + * Where to redirect the browser to if authentication is successful but + * ACEGI_SECURITY_TARGET_URL_KEY is null + */ + private String defaultTargetUrl; + + /** + * The URL destination that this filter intercepts and processes (usually + * something like /j_acegi_security_check) + */ + private String filterProcessesUrl = getDefaultFilterProcessesUrl(); + + //~ Methods ================================================================ + + /** + * Specifies the default filterProcessesUrl for the + * implementation. + * + * @return the default filterProcessesUrl + */ + public abstract String getDefaultFilterProcessesUrl(); + + /** + * Performs actual authentication. + * + * @param request from which to extract parameters and perform the + * authentication + * + * @return the authenticated user + * + * @throws AuthenticationException if authentication fails + */ + public abstract Authentication attemptAuthentication( + HttpServletRequest request) throws AuthenticationException; + + public void setAuthenticationFailureUrl(String authenticationFailureUrl) { + this.authenticationFailureUrl = authenticationFailureUrl; + } + + public String getAuthenticationFailureUrl() { + return authenticationFailureUrl; + } + + public void setAuthenticationManager( + AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + + public AuthenticationManager getAuthenticationManager() { + return authenticationManager; + } + + public void setDefaultTargetUrl(String defaultTargetUrl) { + this.defaultTargetUrl = defaultTargetUrl; + } + + public String getDefaultTargetUrl() { + return defaultTargetUrl; + } + + public void setFilterProcessesUrl(String filterProcessesUrl) { + this.filterProcessesUrl = filterProcessesUrl; + } + + public String getFilterProcessesUrl() { + return filterProcessesUrl; + } + + public void afterPropertiesSet() throws Exception { + if ((filterProcessesUrl == null) || "".equals(filterProcessesUrl)) { + throw new IllegalArgumentException( + "filterProcessesUrl must be specified"); + } + + if ((defaultTargetUrl == null) || "".equals(defaultTargetUrl)) { + throw new IllegalArgumentException( + "defaultTargetUrl must be specified"); + } + + if ((authenticationFailureUrl == null) + || "".equals(authenticationFailureUrl)) { + throw new IllegalArgumentException( + "authenticationFailureUrl must be specified"); + } + + if (authenticationManager == null) { + throw new IllegalArgumentException( + "authenticationManager must be specified"); + } + } + + public void destroy() {} + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + if (!(request instanceof HttpServletRequest)) { + throw new ServletException("Can only process HttpServletRequest"); + } + + if (!(response instanceof HttpServletResponse)) { + throw new ServletException("Can only process HttpServletResponse"); + } + + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + + if (filterProcessesUrl.equals(httpRequest.getServletPath())) { + if (logger.isDebugEnabled()) { + logger.debug("Request is to process authentication"); + } + + Authentication authResult; + + try { + authResult = attemptAuthentication(httpRequest); + } catch (AuthenticationException failed) { + // Authentication failed + if (logger.isDebugEnabled()) { + logger.debug("Authentication request failed: " + + failed.toString()); + } + + httpRequest.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, + failed); + httpRequest.getSession().setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY, + null); + httpResponse.sendRedirect(httpRequest.getContextPath() + + authenticationFailureUrl); + + return; + } + + // Authentication success + if (logger.isDebugEnabled()) { + logger.debug("Authentication success: " + authResult.toString()); + } + + httpRequest.getSession().setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY, + authResult); + + String targetUrl = (String) httpRequest.getSession().getAttribute(ACEGI_SECURITY_TARGET_URL_KEY); + httpRequest.getSession().setAttribute(ACEGI_SECURITY_TARGET_URL_KEY, + null); + + if (targetUrl == null) { + targetUrl = defaultTargetUrl; + } + + if (logger.isDebugEnabled()) { + logger.debug( + "Redirecting to target URL from HTTP Session (or default): " + + targetUrl); + } + + httpResponse.sendRedirect(httpRequest.getContextPath() + targetUrl); + + return; + } + + chain.doFilter(request, response); + } +} diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java index 2d67b5cdcc..4d0b7d0f0b 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilter.java @@ -17,75 +17,24 @@ package net.sf.acegisecurity.ui.webapp; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationException; -import net.sf.acegisecurity.AuthenticationManager; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.ui.AbstractProcessingFilter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; - -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; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** - * Processes an authentication form, putting the result into the - * HttpSession. - * - *

- * This filter is responsible for processing authentication requests. A user - * will typically authenticate once using a login form, and this filter - * processes that form. If authentication is successful, the resulting {@link - * Authentication} object will be placed into the HttpSession - * with the attribute defined by {@link - * HttpSessionIntegrationFilter#ACEGI_SECURITY_AUTHENTICATION_KEY}. - *

+ * Processes an authentication form. * *

* 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. + * password. The parameter names to use are contained in the static fields + * {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} and {@link + * #ACEGI_SECURITY_FORM_PASSWORD_KEY}. *

* - *

- * If authentication fails, the AuthenticationException will be - * placed into the HttpSession with the attribute defined by - * {@link #ACEGI_SECURITY_LAST_EXCEPTION_KEY}. - *

- * - *

- * To use this filter, it is necessary to specify the following properties: - *

- * - * - * *

* Do not use this class directly. Instead configure * web.xml to use the {@link @@ -96,175 +45,40 @@ import javax.servlet.http.HttpServletResponse; * @author Colin Sampaleanu * @version $Id$ */ -public class AuthenticationProcessingFilter implements Filter, InitializingBean { +public class AuthenticationProcessingFilter extends AbstractProcessingFilter { //~ Static fields/initializers ============================================= - 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"; - public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION"; - private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilter.class); - - //~ Instance fields ======================================================== - - private AuthenticationManager authenticationManager; - - /** Where to redirect the browser to if authentication fails */ - private String authenticationFailureUrl; - - /** - * Where to redirect the browser to if authentication is successful but - * ACEGI_SECURITY_TARGET_URL_KEY is null - */ - private String defaultTargetUrl; - - /** - * The URL destination that this filter intercepts and processes (usually - * /j_acegi_security_check) - */ - private String filterProcessesUrl = "/j_acegi_security_check"; //~ Methods ================================================================ - public void setAuthenticationFailureUrl(String authenticationFailureUrl) { - this.authenticationFailureUrl = authenticationFailureUrl; + /** + * This filter by default responds to /j_acegi_security_check. + * + * @return the default + */ + public String getDefaultFilterProcessesUrl() { + return "/j_acegi_security_check"; } - public String getAuthenticationFailureUrl() { - return authenticationFailureUrl; - } + public Authentication attemptAuthentication(HttpServletRequest request) + throws AuthenticationException { + String username = request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY); + String password = request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY); - 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 (username == null) { + username = ""; } - if ((defaultTargetUrl == null) || "".equals(defaultTargetUrl)) { - throw new IllegalArgumentException( - "defaultTargetUrl must be specified"); + if (password == null) { + password = ""; } - if ((authenticationFailureUrl == null) - || "".equals(authenticationFailureUrl)) { - throw new IllegalArgumentException( - "authenticationFailureUrl must be specified"); - } + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, + password); - if (authenticationManager == null) { - throw new IllegalArgumentException( - "authenticationManager must be specified"); - } - } - - public void destroy() {} - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - if (!(request instanceof HttpServletRequest)) { - throw new ServletException("Can only process HttpServletRequest"); - } - - if (!(response instanceof HttpServletResponse)) { - throw new ServletException("Can only process HttpServletResponse"); - } - - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpServletResponse httpResponse = (HttpServletResponse) response; - - if (filterProcessesUrl.equals(httpRequest.getServletPath())) { - if (logger.isDebugEnabled()) { - logger.debug("Request is to process Acegi login form"); - } - - String username = httpRequest.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY); - String password = httpRequest.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY); - - if (username == null) { - username = ""; - } - - if (password == null) { - password = ""; - } - - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, - password); - - Authentication authResult; - - try { - authResult = authenticationManager.authenticate(authRequest); - } catch (AuthenticationException failed) { - // Authentication failed - if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username - + " failed: " + failed.toString()); - } - - httpRequest.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, - failed); - httpRequest.getSession().setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY, - null); - httpResponse.sendRedirect(httpRequest.getContextPath() - + authenticationFailureUrl); - - return; - } - - // Authentication success - if (logger.isDebugEnabled()) { - logger.debug("Authentication success: " + authResult.toString()); - } - - httpRequest.getSession().setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY, - authResult); - - String targetUrl = (String) httpRequest.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY); - httpRequest.getSession().setAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY, - null); - - if (targetUrl == null) { - targetUrl = defaultTargetUrl; - } - - if (logger.isDebugEnabled()) { - logger.debug( - "Redirecting to target URL from HTTP Session (or default): " - + targetUrl); - } - - httpResponse.sendRedirect(httpRequest.getContextPath() + targetUrl); - - return; - } - - chain.doFilter(request, response); + return this.getAuthenticationManager().authenticate(authRequest); } public void init(FilterConfig filterConfig) throws ServletException {}