From db96650d994721ba4eb50f7d5297b35c8791d5b0 Mon Sep 17 00:00:00 2001 From: Scott McCrory Date: Sat, 23 Sep 2006 19:48:39 +0000 Subject: [PATCH] SEC-319: Reverted to 1.0.1 version to delay these changes to 1.1.0, based on small breakage of backward compatability. --- ...eminderAuthenticationProcessingFilter.java | 122 +++++++++++++----- 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java index bd95cc48d2..2f3ce4573f 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java @@ -15,40 +15,36 @@ package org.acegisecurity.ui.webapp; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; + import org.acegisecurity.context.HttpSessionContextIntegrationFilter; import org.acegisecurity.context.SecurityContext; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + /** - * Extends Acegi's AuthenticationProcessingFilter to pick up CA/Netegrity Siteminder headers. - * - *

Also provides a backup form-based authentication and the ability set source key names.

- * - *

Siteminder must present two headers to this filter, a username and password. You must set the + * Extends Acegi's AuthenticationProcessingFilter to pick up CA/Netegrity Siteminder headers.

Also provides a + * backup form-based authentication and the ability set source key names.

+ *

Siteminder must present two headers to this filter, a username and password. You must set the * header keys before this filter is used for authentication, otherwise Siteminder checks will be skipped. If the * Siteminder check is unsuccessful (i.e. if the headers are not found), then the form parameters will be checked (see * next paragraph). This allows applications to optionally function even when their Siteminder infrastructure is * unavailable, as is often the case during development.

- * - *

Login forms must present two parameters to this filter: a username and password. If not + *

Login forms must present two parameters to this filter: a username and password. If not * specified, the parameter names to use are contained in the static fields {@link #ACEGI_SECURITY_FORM_USERNAME_KEY} * and {@link #ACEGI_SECURITY_FORM_PASSWORD_KEY}.

- * - *

Do not use this class directly. Instead, configure web.xml to use the {@link + *

Do not use this class directly. Instead, configure web.xml to use the {@link * org.acegisecurity.util.FilterToBeanProxy}.

- * - * @author Scott McCrory - * @version $Id$ */ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProcessingFilter { - //~ Static fields/initializers ===================================================================================== /** Log instance for debugging */ @@ -56,15 +52,21 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc //~ Instance fields ================================================================================================ + /** Form password request key. */ + private String formPasswordParameterKey = null; + /** Form username request key. */ private String formUsernameParameterKey = null; + /** Siteminder password header key. */ + private String siteminderPasswordHeaderKey = null; + /** Siteminder username header key. */ private String siteminderUsernameHeaderKey = null; //~ Constructors =================================================================================================== - /** +/** * Basic constructor. */ public SiteminderAuthenticationProcessingFilter() { @@ -74,19 +76,24 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc //~ Methods ======================================================================================================== /** + * * @see org.acegisecurity.ui.AbstractProcessingFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest) */ - public Authentication attemptAuthentication(final HttpServletRequest request) throws AuthenticationException { - + public Authentication attemptAuthentication(HttpServletRequest request) + throws AuthenticationException { String username = null; + String password = null; - // Check the Siteminder header for identification info - if ((siteminderUsernameHeaderKey != null) && (siteminderUsernameHeaderKey.length() > 0)) { + // Check the Siteminder headers for authentication info + if ((siteminderUsernameHeaderKey != null) && (siteminderUsernameHeaderKey.length() > 0) + && (siteminderPasswordHeaderKey != null) && (siteminderPasswordHeaderKey.length() > 0)) { username = request.getHeader(siteminderUsernameHeaderKey); + password = request.getHeader(siteminderPasswordHeaderKey); } - // If the Siteminder identification info wasn't available, then try to get it from the form - if ((username == null) || (username.length() == 0)) { + // If the Siteminder authentication info wasn't available, then get it + // from the form parameters + if ((username == null) || (username.length() == 0) || (password == null) || (password.length() == 0)) { if (logger.isDebugEnabled()) { logger.debug("Siteminder headers not found for authentication, so trying to use form values"); } @@ -97,6 +104,7 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc username = request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY); } + password = obtainPassword(request); } // Convert username and password to upper case. This is normally not a @@ -109,9 +117,14 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc username = ""; } - // Pass in a null password value because it isn't relevant for Siteminder. - // Of course the AuthenticationManager needs to not care! - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, null); + if (password != null) { + password = password.toUpperCase(); + } else { + // If password is null, set to blank to avoid a NPE. + password = ""; + } + + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); @@ -122,6 +135,15 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc return this.getAuthenticationManager().authenticate(authRequest); } + /** + * Returns the form password parameter key. + * + * @return The form password parameter key. + */ + public String getFormPasswordParameterKey() { + return formPasswordParameterKey; + } + /** * Returns the form username parameter key. * @@ -131,6 +153,15 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc return formUsernameParameterKey; } + /** + * Returns the Siteminder password header key. + * + * @return The Siteminder password header key. + */ + public String getSiteminderPasswordHeaderKey() { + return siteminderPasswordHeaderKey; + } + /** * Returns the Siteminder username header key. * @@ -141,14 +172,20 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc } /** - * Overridden method to always return a null (Siteminder doesn't pass on the password). + * Overridden method to obtain different value depending on whether Siteminder or form validation is being + * performed. * * @param request so that request attributes can be retrieved + * * @return the password that will be presented in the Authentication request token to the - * AuthenticationManager (null). + * AuthenticationManager */ - protected String obtainPassword(final HttpServletRequest request) { - return null; + protected String obtainPassword(HttpServletRequest request) { + if ((formPasswordParameterKey != null) && (formPasswordParameterKey.length() > 0)) { + return request.getParameter(formPasswordParameterKey); + } else { + return request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY); + } } /** @@ -160,7 +197,6 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc * javax.servlet.http.HttpServletResponse) */ protected boolean requiresAuthentication(final HttpServletRequest request, final HttpServletResponse response) { - String uri = request.getRequestURI(); int pathParamIndex = uri.indexOf(';'); @@ -172,8 +208,8 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc //attempt authentication if j_secuity_check is present or if the getDefaultTargetUrl() //is present and user is not already authenticated. boolean bAuthenticated = false; - SecurityContext context = (SecurityContext) request.getSession().getAttribute( - HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); + SecurityContext context = (SecurityContext) request.getSession() + .getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); if (context != null) { Authentication auth = context.getAuthentication(); @@ -186,7 +222,7 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc // if true is returned then authentication will be attempted. boolean bAttemptAuthentication = (uri.endsWith(request.getContextPath() + getFilterProcessesUrl())) - || ((getDefaultTargetUrl() != null) && uri.endsWith(getDefaultTargetUrl()) && !bAuthenticated); + || ((getDefaultTargetUrl() != null) && uri.endsWith(getDefaultTargetUrl()) && !bAuthenticated); if (logger.isDebugEnabled()) { logger.debug("Authentication attempted for the following URI ==> " + uri + " is " + bAttemptAuthentication); @@ -195,6 +231,15 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc return bAttemptAuthentication; } + /** + * Sets the form password parameter key. + * + * @param key The form password parameter key. + */ + public void setFormPasswordParameterKey(final String key) { + this.formPasswordParameterKey = key; + } + /** * Sets the form username parameter key. * @@ -204,6 +249,15 @@ public class SiteminderAuthenticationProcessingFilter extends AuthenticationProc this.formUsernameParameterKey = key; } + /** + * Sets the Siteminder password header key. + * + * @param key The Siteminder password header key. + */ + public void setSiteminderPasswordHeaderKey(final String key) { + this.siteminderPasswordHeaderKey = key; + } + /** * Sets the Siteminder username header key. *