From: chris_schultz Date: Fri, 2 Nov 2007 16:31:24 +0000 (+0000) Subject: Added post-login forward capability (original patch posted to the sourceforge.net... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=7c3ea94af3493ed7752c6661169501a6015dc73d;p=securityfilter.git Added post-login forward capability (original patch posted to the sourceforge.net forums). --- diff --git a/src/share/org/securityfilter/authenticator/FormAuthenticator.java b/src/share/org/securityfilter/authenticator/FormAuthenticator.java index 4c8f473..55ad1a8 100644 --- a/src/share/org/securityfilter/authenticator/FormAuthenticator.java +++ b/src/share/org/securityfilter/authenticator/FormAuthenticator.java @@ -1,7 +1,7 @@ /* - * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator/FormAuthenticator.java,v 1.11 2005/02/22 11:02:16 maxcooper Exp $ - * $Revision: 1.11 $ - * $Date: 2005/02/22 11:02:16 $ + * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator/FormAuthenticator.java,v 1.12 2007/11/02 16:31:24 chris_schultz Exp $ + * $Revision: 1.12 $ + * $Date: 2007/11/02 16:31:24 $ * * ==================================================================== * The SecurityFilter Software License, Version 1.1 @@ -66,16 +66,22 @@ import javax.servlet.http.*; import java.io.IOException; import java.security.Principal; +import java.util.Enumeration; +import java.net.URLEncoder; +import java.io.UnsupportedEncodingException; + /** * FormAuthenticator - authenticator implementation for the FORM auth method. * * @author Max Cooper (max@maxcooper.com) - * @version $Revision: 1.11 $ $Date: 2005/02/22 11:02:16 $ + * @author Chris Schultz (chris@christopherschultz.net) + * @version $Revision: 1.12 $ $Date: 2007/11/02 16:31:24 $ */ public class FormAuthenticator implements Authenticator { public static final String LOGIN_SUBMIT_PATTERN_KEY = "loginSubmitPattern"; public static final String DEFAULT_LOGIN_SUBMIT_PATTERN = "/j_security_check"; + protected String loginSubmitPattern; protected static final String FORM_USERNAME = "j_username"; @@ -93,6 +99,79 @@ public class FormAuthenticator implements Authenticator { protected SecurityRealmInterface realm; + + /** + * The key that will be used to look up the filter init parameter + * that specifies the "forward" parameter used for post-login forward + * requests. + * + * @see #forwardParameterName + */ + public static final String FORWARD_PARAMETER_KEY = "forwardParameter"; + + /** + * The key that will be used to look up the filter init parameter + * that specifies the "forwardMode" parameter used for post-login forward + * requests. + * + * @see #forwardModeParameterName + */ + public static final String FORWARD_MODE_PARAMETER_KEY = "forwardModeParameter"; + + /** + * The key that will be used to look up the filter init parameter + * that specifies the "forwardParameters" parameter used for post-login + * forward requests. + * + * @see #forwardParametersParameterName + */ + public static final String FORWARD_PARAMETERS_PARAMETER_KEY = "forwardParametersParameter"; + + /** + * The default value for {@link #forwardParameterName}. + */ + public static final String DEFAULT_FORWARD_PARAMETER_NAME = "forward"; + /** + * The default value for {@link #forwardModeParameterName}. + */ + public static final String DEFAULT_FORWARD_MODE_PARAMETER_NAME = "forward-mode"; + /** + * The default value for {@link #forwardParametersParameterName}. + */ + public static final String DEFAULT_FORWARD_PARAMETERS_PARAMETER_NAME = "forward-parameters"; + + /** + * The name of the request parameter that will be recognized as a + * post-login forward request. + * + * @see #forwardParameterName + * @see #DEFAULT_FORWARD_PARAMETER_NAME + */ + protected String forwardParameterName; + + /** + * The name of the request parameter that will be checked for + * either "forward" or "redirect" when processing a post-login forward + * request. The default is "redirect". + * + * @see #forwardModeParameterName + * @see #DEFAULT_FORWARD_MODE_PARAMETER_NAME + */ + protected String forwardModeParameterName; + + /** + * The name of the request parameter that will be checked to see + * whether the login request's request parameters should be forwarded + * to the destination URI when processing a post-login forward request. + * The options are "true" (to forward the request parameters) or "false" + * (to forward to the destination URI with no request parameter + * pass-through. The default is "false". + * + * @see #forwardParameterName + * @see #DEFAULT_FORWARD_PARAMETERS_PARAMETER_NAME + */ + protected String forwardParametersParameterName; + /** * Initilize this Authenticator. * @@ -109,6 +188,21 @@ public class FormAuthenticator implements Authenticator { loginSubmitPattern = DEFAULT_LOGIN_SUBMIT_PATTERN; } + // "forward" parameter + forwardParameterName = filterConfig.getInitParameter(FORWARD_PARAMETER_KEY); + if(null == forwardParameterName) + forwardParameterName = DEFAULT_FORWARD_PARAMETER_NAME; + + // "forward-mode" parameter name + forwardModeParameterName = filterConfig.getInitParameter(FORWARD_MODE_PARAMETER_KEY); + if(null == forwardModeParameterName) + forwardModeParameterName = DEFAULT_FORWARD_MODE_PARAMETER_NAME; + + // "forward-parameters" parameter name + forwardParametersParameterName = filterConfig.getInitParameter(FORWARD_PARAMETERS_PARAMETER_KEY); + if(null == forwardParametersParameterName) + forwardParametersParameterName = DEFAULT_FORWARD_PARAMETERS_PARAMETER_NAME; + // default page defaultPage = securityConfig.getDefaultPage(); @@ -174,44 +268,63 @@ public class FormAuthenticator implements Authenticator { // process login form submittal if (request.getMatchableURL().endsWith(loginSubmitPattern)) { - String username = request.getParameter(FORM_USERNAME); - String password = request.getParameter(FORM_PASSWORD); - Principal principal = realm instanceof FlexibleRealmInterface ? - ((FlexibleRealmInterface) realm).authenticate(request) - : realm.authenticate(username, password); - if (principal != null) { - // login successful - - // invalidate old session if the user was already authenticated, and they logged in as a different user - if (request.getUserPrincipal() != null - && false == request.getUserPrincipal().equals(principal)) { - request.getSession().invalidate(); - } - - // manage persistent login info, if persistent login management is enabled - // and username/password are passed as part of logon - if (persistentLoginManager != null - && username != null && password != null) { - String rememberme = request.getParameter(FORM_REMEMBERME); - // did the user request that their login be persistent? - if (rememberme != null) { - // remember login - persistentLoginManager.rememberLogin(request, response, username, password); - } else { - // forget login - persistentLoginManager.forgetLogin(request, response); - } - } - - request.setUserPrincipal(principal); - String continueToURL = getContinueToURL(request); - // This is the url that the user was initially accessing before being prompted for login. - response.sendRedirect(response.encodeRedirectURL(continueToURL)); - } else { - // login failed - forward to error page - request.getRequestDispatcher(errorPage).forward(request, response); - } - return true; + String username = request.getParameter(FORM_USERNAME); + String password = request.getParameter(FORM_PASSWORD); + Principal principal = realm instanceof FlexibleRealmInterface ? + ((FlexibleRealmInterface) realm).authenticate(request) + : realm.authenticate(username, password); + if (principal != null) { + // login successful + + // invalidate old session if the user was already authenticated, and they logged in as a different user + if (request.getUserPrincipal() != null + && false == request.getUserPrincipal().equals(principal)) { + request.getSession().invalidate(); + } + + // manage persistent login info, if persistent login management is enabled + // and username/password are passed as part of logon + if (persistentLoginManager != null + && username != null && password != null) { + String rememberme = request.getParameter(FORM_REMEMBERME); + // did the user request that their login be persistent? + if (rememberme != null) { + // remember login + persistentLoginManager.rememberLogin(request, response, username, password); + } else { + // forget login + persistentLoginManager.forgetLogin(request, response); + } + } + + request.setUserPrincipal(principal); + + + Forward fwd = getForward(request); + + if(fwd.redirect) + { + String uri = response.encodeRedirectURL(fwd.uri); + + // Parameters only need to be explicitly forwarded + // when we're doing a redirect. + if(fwd.forwardParameters) + { + StringBuffer q = this.getFilteredQueryString(request); + if(null != q) + uri += q; + } + + response.sendRedirect(uri); + } + else + request.getRequestDispatcher(fwd.uri). + forward(request, response); + } else { + // login failed - forward to error page + request.getRequestDispatcher(errorPage).forward(request, response); + } + return true; } return false; @@ -324,6 +437,126 @@ public class FormAuthenticator implements Authenticator { } return uri; } + + /** + * A class to represent information about the destination after login. + */ + private static class Forward + { + /** + * The destination URI. + */ + String uri; + + /** + * true if this Forward should be redirected through the + * client. + */ + boolean redirect; + + /** + * true if the forward should include all the parameters + * from the current request. + */ + boolean forwardParameters; + + Forward(String uri, boolean redirect, boolean forwardParameters) + { + this.uri = uri; + this.redirect = redirect; + this.forwardParameters = forwardParameters; + } + } + + /** + * Gets post-login destination information. + */ + private Forward getForward(HttpServletRequest request) + { + String uri = request.getParameter(forwardParameterName); + boolean redirect; + boolean forwardParameters; + + // Was there a request to forward somewhere else after login? + if(null != uri && 0 < uri.trim().length()) + { + // Default to redirect + redirect = !"forward".equalsIgnoreCase(request.getParameter(forwardModeParameterName)); + // Default to do-not-forward-parameters + forwardParameters = "true".equalsIgnoreCase(request.getParameter(forwardParametersParameterName)); + } + else + { + // No forward request: go to the "continue URL" which is either + // the user's original request or the default page to hit after login. + uri = getContinueToURL(request); + redirect = true; + forwardParameters = false; + } + + return new Forward(uri, redirect, forwardParameters); + } + + /** + * Gets the query string that will be used when a login request + * has included a "forward" directive. We don't want to include + * username and password information in the resulting URL, so we + * re-build the query string by stripping-out the sensitive + * parameters. We also strip-out the "forward" parameter information + * because it has served its purpose. + * + * @param request The request being processed. + * + * @return A StringBuffer containing the query string (starting with '?') + * with all of the current request's parameters except for + * the username, password, and forward-related parameters. + */ + private StringBuffer getFilteredQueryString(HttpServletRequest request) + throws UnsupportedEncodingException + { + Enumeration e = request.getParameterNames(); + + StringBuffer queryString = null; + + if(e.hasMoreElements()) + { + boolean first = true; + queryString = new StringBuffer(); + + while(e.hasMoreElements()) + { + String name = (String)e.nextElement(); + + // Filter-out login-related parameters + if(!(FORM_USERNAME.equals(name) + || FORM_PASSWORD.equals(name) + || forwardParameterName.equals(name) + || forwardModeParameterName.equals(name) + || forwardParametersParameterName.equals(name))) + { + String[] values = request.getParameterValues(name); + + for(int i=0; i <%@ page import="org.securityfilter.example.Constants"%> +<%@ page import="org.securityfilter.authenticator.FormAuthenticator"%> - + <%=Constants.LOGIN_TITLE%> @@ -29,8 +30,28 @@ Password: value="<%=Constants.VALID_PASSWORD%>" >

+

+You may set these post-login forward options if you'd like:
+URL:
+ +Method: + + + + + +
+ +Include parameters: + + + + + +

+ - \ No newline at end of file +