فهرست منبع

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

Scott McCrory 19 سال پیش
والد
کامیت
db96650d99
1فایلهای تغییر یافته به همراه88 افزوده شده و 34 حذف شده
  1. 88 34
      core/src/main/java/org/acegisecurity/ui/webapp/SiteminderAuthenticationProcessingFilter.java

+ 88 - 34
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.
- * 
- * <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.
      *