SEC-319: Reverted to 1.0.1 version to delay these changes to 1.1.0, based on small breakage of backward compatability.

This commit is contained in:
Scott McCrory 2006-09-23 19:48:39 +00:00
parent ef6d6cd03e
commit db96650d99
1 changed files with 88 additions and 34 deletions

View File

@ -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.
*
* <P>Also provides a backup form-based authentication and the ability set source key names.</p>
*
* <P><B>Siteminder</B> must present two <B>headers</B> to this filter, a username and password. You must set the
* Extends Acegi's AuthenticationProcessingFilter to pick up CA/Netegrity Siteminder headers.<P>Also provides a
* backup form-based authentication and the ability set source key names.</p>
* <P><B>Siteminder</B> must present two <B>headers</B> 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.</p>
*
* <P><B>Login forms</B> must present two <B>parameters</B> to this filter: a username and password. If not
* <P><B>Login forms</B> must present two <B>parameters</B> 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}.</p>
*
* <P><B>Do not use this class directly.</B> Instead, configure <code>web.xml</code> to use the {@link
* <P><B>Do not use this class directly.</B> Instead, configure <code>web.xml</code> to use the {@link
* org.acegisecurity.util.FilterToBeanProxy}.</p>
*
* @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 <code>Authentication</code> request token to the
* <code>AuthenticationManager</code> (null).
* <code>AuthenticationManager</code>
*/
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.
*