Update of /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv24774/src/share/org/securityfilter/authenticator
Modified Files:
FormAuthenticator.java
Log Message:
Added post-login forward capability (original patch posted to the sourceforge.net forums).
Index: FormAuthenticator.java
===================================================================
RCS file: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator/FormAuthenticator.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** FormAuthenticator.java 22 Feb 2005 11:02:16 -0000 1.11
--- FormAuthenticator.java 2 Nov 2007 16:31:24 -0000 1.12
***************
*** 67,74 ****
--- 67,79 ----
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 (ma...@ma...)
+ * @author Chris Schultz (ch...@ch...)
* @version $Revision$ $Date$
*/
***************
*** 77,80 ****
--- 82,86 ----
public static final String LOGIN_SUBMIT_PATTERN_KEY = "loginSubmitPattern";
public static final String DEFAULT_LOGIN_SUBMIT_PATTERN = "/j_security_check";
+
protected String loginSubmitPattern;
***************
*** 94,97 ****
--- 100,176 ----
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.
***************
*** 110,113 ****
--- 189,207 ----
}
+ // "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();
***************
*** 175,216 ****
// 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;
}
--- 269,329 ----
// 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);
!
!
! 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;
}
***************
*** 325,328 ****
--- 438,561 ----
return uri;
}
+
+ /**
+ * A class to represent information about the destination after login.
+ */
+ private static class Forward
+ {
+ /**
+ * The destination URI.
+ */
+ String uri;
+
+ /**
+ * <code>true</code> if this Forward should be redirected through the
+ * client.
+ */
+ boolean redirect;
+
+ /**
+ * <code>true</code> 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<values.length; ++i)
+ {
+ if(first)
+ {
+ queryString.append('?');
+ first = false;
+ }
+ else
+ queryString.append('&');
+
+ queryString
+ .append(URLEncoder.encode(name, "UTF-8"))
+ .append('=')
+ .append(URLEncoder.encode(values[i], "UTF-8"));
+ }
+ }
+ }
+ }
+
+ return queryString;
+ }
}
|