added FlexibleSecurityRealm interface
authormaxcooper <maxcooper>
Tue, 22 Feb 2005 11:01:59 +0000 (11:01 +0000)
committermaxcooper <maxcooper>
Tue, 22 Feb 2005 11:01:59 +0000 (11:01 +0000)
fixed response code bug for form-based login (was 401, now 200)
bug: 935921
bug: 1143612

16 files changed:
HISTORY
build-webapps.xml
build.xml
src/example/org/securityfilter/example/Constants.java
src/example/org/securityfilter/example/realm/TrivialFlexibleRealm.java [new file with mode: 0644]
src/share/org/securityfilter/authenticator/FormAuthenticator.java
src/share/org/securityfilter/realm/FlexibleRealmInterface.java [new file with mode: 0644]
src/test/org/securityfilter/test/http/TestBase.java
src/test/org/securityfilter/test/http/form/CookiesDisabledTest.java
src/test/org/securityfilter/test/http/form/DefaultPageTest.java
src/test/org/securityfilter/test/http/form/JustInTimeTest.java
src/test/org/securityfilter/test/http/form/LogoutTest.java
src/test/org/securityfilter/test/http/form/PathTricksTest.java
src/test/org/securityfilter/test/http/form/PostMethodTest.java
src/test/org/securityfilter/test/http/form/SessionInvalidationTest.java
src/test/org/securityfilter/test/http/form/UTFTest.java

diff --git a/HISTORY b/HISTORY
index d7545a0..e830ee1 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,6 @@
-$Id: HISTORY,v 1.28 2004/12/13 14:46:53 maxcooper Exp $
-$Revision: 1.28 $
-$Date: 2004/12/13 14:46:53 $
+$Id: HISTORY,v 1.29 2005/02/22 11:01:59 maxcooper Exp $
+$Revision: 1.29 $
+$Date: 2005/02/22 11:01:59 $
 
 
 Security Filter v@PROJECT.VERSION@
@@ -11,6 +11,18 @@ http://securityfilter.sourceforge.net/
 This document describes the history of the Security Filter project by lising the
 changes made for each release.
 
+Changes since the last release:
+===============================
+* Fixed form-based login HTTP response code (was 401, now 200), including an automated test:
+http://sourceforge.net/tracker/index.php?func=detail&aid=935921&group_id=59484&atid=491164
+http://sourceforge.net/tracker/index.php?func=detail&aid=1143612&group_id=59484&atid=491164
+
+* Added FlexibleRealmInterface to allow more flexible processing of login information.
+
+* Refactored some assert... method signatures in the automated tests to take the expected
+value first, which follows the JUnit example. Also changed some calls to JUnit assert...
+methods to put the expected value first.
+
 
 Release 2.0, 2004-Dec-13
 ========================
index a41d6c7..f981984 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0"?>
 
 <!--
-$Id: build-webapps.xml,v 1.9 2004/01/26 10:53:49 maxcooper Exp $
-$Revision: 1.9 $
-$Date: 2004/01/26 10:53:49 $
+$Id: build-webapps.xml,v 1.10 2005/02/22 11:02:04 maxcooper Exp $
+$Revision: 1.10 $
+$Date: 2005/02/22 11:02:04 $
 -->
 
 <!DOCTYPE project [
@@ -57,6 +57,19 @@ $Date: 2004/01/26 10:53:49 $
       <pathelement location="${web.dir}/example"/>
    </path>
 
+   <!-- ========== flexible-example web app ================================================================================= -->
+
+   <path id="flexible-example.src.path" path="${src.example.dir}"/>
+
+   <fileset id="flexible-example.lib.files" dir="${build.lib.dir}">
+      <patternset refid="common.lib.files"/>
+   </fileset>
+
+   <path id="flexible-example.static.path">
+      <pathelement location="${web.dir}/share"/>
+      <pathelement location="${web.dir}/flexible-example"/>
+   </path>
+
    <!-- ========== basic web app =================================================================================== -->
 
    <path id="basic.src.path" path="${src.example.dir}"/>
@@ -108,6 +121,9 @@ $Date: 2004/01/26 10:53:49 $
          <param name="webapp.name" value="example"/>
       </antcall>
       <antcall target="build-webapp" inheritall="false">
+         <param name="webapp.name" value="flexible-example"/>
+      </antcall>
+      <antcall target="build-webapp" inheritall="false">
          <param name="webapp.name" value="basic"/>
       </antcall>
       <antcall target="build-webapp" inheritall="false">
@@ -127,6 +143,9 @@ $Date: 2004/01/26 10:53:49 $
          <param name="webapp.name" value="example"/>
       </antcall>
       <antcall target="webapp-war" inheritall="false">
+         <param name="webapp.name" value="flexible-example"/>
+      </antcall>
+      <antcall target="webapp-war" inheritall="false">
          <param name="webapp.name" value="basic"/>
       </antcall>
       <antcall target="webapp-war" inheritall="false">
@@ -146,6 +165,9 @@ $Date: 2004/01/26 10:53:49 $
          <property name="webapp.name" value="${project.name}-example"/>
       </ant>
       <ant antfile="deploy.xml" inheritall="false" target="deploy">
+         <property name="webapp.name" value="${project.name}-flexible-example"/>
+      </ant>
+      <ant antfile="deploy.xml" inheritall="false" target="deploy">
          <property name="webapp.name" value="${project.name}-basic"/>
       </ant>
       <ant antfile="deploy.xml" inheritall="false" target="deploy">
@@ -165,6 +187,9 @@ $Date: 2004/01/26 10:53:49 $
          <property name="webapp.name" value="${project.name}-example"/>
       </ant>
       <ant antfile="deploy.xml" inheritall="false" target="undeploy">
+         <property name="webapp.name" value="${project.name}-flexible-example"/>
+      </ant>
+      <ant antfile="deploy.xml" inheritall="false" target="undeploy">
          <property name="webapp.name" value="${project.name}-basic"/>
       </ant>
       <ant antfile="deploy.xml" inheritall="false" target="undeploy">
@@ -228,7 +253,9 @@ $Date: 2004/01/26 10:53:49 $
          debug="${compile.debug}"
          debuglevel="${compile.debuglevel}"
          deprecation="${compile.deprecation}"
-         optimize="${compile.optimize}">
+         optimize="${compile.optimize}"
+         source="${securityfilter.java.version}"
+         target="${securityfilter.java.version}">
          <src refid="${webapp.name}.src.path"/>
          <classpath refid="webapp.classpath"/>
       </javac>
index ad28e05..34c726d 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0"?>
 
 <!--
-$Id: build.xml,v 1.21 2003/07/07 04:20:22 maxcooper Exp $
-$Revision: 1.21 $
-$Date: 2003/07/07 04:20:22 $
+$Id: build.xml,v 1.22 2005/02/22 11:02:07 maxcooper Exp $
+$Revision: 1.22 $
+$Date: 2005/02/22 11:02:07 $
 -->
 
 <!DOCTYPE project [
@@ -34,7 +34,9 @@ $Date: 2003/07/07 04:20:22 $
          debug="${compile.debug}"
          debuglevel="${compile.debuglevel}"
          optimize="${compile.optimize}"
-         deprecation="${compile.deprecation}">
+         deprecation="${compile.deprecation}"
+         source="${securityfilter.java.version}"
+         target="${securityfilter.java.version}">
          <classpath refid="compile.classpath"/>
       </javac>
       <!-- catalina adapter realm -->
@@ -43,7 +45,9 @@ $Date: 2003/07/07 04:20:22 $
          debug="${compile.debug}"
          debuglevel="${compile.debuglevel}"
          optimize="${compile.optimize}"
-         deprecation="${compile.deprecation}">
+         deprecation="${compile.deprecation}"
+         source="${securityfilter.java.version}"
+         target="${securityfilter.java.version}">
          <classpath refid="compile.classpath"/>
       </javac>
    </target>
@@ -244,7 +248,9 @@ $Date: 2003/07/07 04:20:22 $
          debug="${compile.debug}"
          debuglevel="${compile.debuglevel}"
          optimize="${compile.optimize}"
-         deprecation="${compile.deprecation}">
+         deprecation="${compile.deprecation}"
+         source="${securityfilter.java.version}"
+         target="${securityfilter.java.version}">
          <classpath refid="test-compile.classpath"/>
          <sourcepath location="${src.example.dir}"/>
       </javac>
index d94e12e..56ded84 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/example/org/securityfilter/example/Constants.java,v 1.5 2004/01/26 10:55:37 maxcooper Exp $
- * $Revision: 1.5 $
- * $Date: 2004/01/26 10:55:37 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/example/org/securityfilter/example/Constants.java,v 1.6 2005/02/22 11:02:10 maxcooper Exp $
+ * $Revision: 1.6 $
+ * $Date: 2005/02/22 11:02:10 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -59,7 +59,7 @@ package org.securityfilter.example;
  * Constants - constants for the example applications to facilitate testing
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.5 $ $Date: 2004/01/26 10:55:37 $
+ * @version $Revision: 1.6 $ $Date: 2005/02/22 11:02:10 $
  */
 public interface Constants {
 
@@ -83,6 +83,7 @@ public interface Constants {
    public static final String LOGIN_USERNAME_FIELD = "j_username";
    public static final String LOGIN_PASSWORD_FIELD = "j_password";
    public static final String LOGIN_REMEMBERME_FIELD = "j_rememberme";
+   public static final String LOGIN_AUTHDATA_FIELD = "AuthData";
 
    // secure page constants
    public static final String SECURE_TITLE = COMMON_TITLE_BASE + "Secure Page";
diff --git a/src/example/org/securityfilter/example/realm/TrivialFlexibleRealm.java b/src/example/org/securityfilter/example/realm/TrivialFlexibleRealm.java
new file mode 100644 (file)
index 0000000..5d88053
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/example/org/securityfilter/example/realm/TrivialFlexibleRealm.java,v 1.1 2005/02/22 11:02:16 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2005/02/22 11:02:16 $
+ *
+ * ====================================================================
+ * The SecurityFilter Software License, Version 1.1
+ *
+ * (this license is derived and fully compatible with the Apache Software
+ * License - see http://www.apache.org/LICENSE.txt)
+ *
+ * Copyright (c) 2002 SecurityFilter.org. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by
+ *        SecurityFilter.org (http://www.securityfilter.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "SecurityFilter" must not be used to endorse or promote
+ *    products derived from this software without prior written permission.
+ *    For written permission, please contact license@securityfilter.org .
+ *
+ * 5. Products derived from this software may not be called "SecurityFilter",
+ *    nor may "SecurityFilter" appear in their name, without prior written
+ *    permission of SecurityFilter.org.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE SECURITY FILTER PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ */
+
+package org.securityfilter.example.realm;
+
+import java.security.Principal;
+import java.util.ArrayList;
+
+import org.securityfilter.example.Constants;
+import org.securityfilter.realm.FlexibleRealmInterface;
+import org.securityfilter.filter.SecurityRequestWrapper;
+import org.securityfilter.realm.SimpleSecurityRealmBase;
+import org.securityfilter.realm.SimplePrincipal;
+
+/**
+ * Trivial implementation of the FlexibleRealmInterface.
+ *
+ * There is one user: username is 'username', password is 'password'
+ * And this user is in one role: 'inthisrole'
+ * The SecurityRequestWrapper should have username:password in parameter AuthData
+ * If AuthData is not present, uses standard j_username/j_password parameters
+ *
+ * @author anonymous
+ * @version $Revision: 1.1 $ $Date: 2005/02/22 11:02:16 $
+ */
+public class TrivialFlexibleRealm extends SimpleSecurityRealmBase implements FlexibleRealmInterface {
+
+   private String exampleProperty;
+
+   private static final String AUTHENTICATION_DATA = "AuthData";
+   private static final String FORM_USERNAME = "j_username";
+   private static final String FORM_PASSWORD = "j_password";
+
+   /**
+    * Authenticate a user.
+    *
+    * The SecurityRequetWrapper holds username:password in parameter AuthData
+    *
+    * @param reqWrapper The request which holds username:password in param AuthData
+    *
+    * @return null if the user cannot be authenticated, otherwise a Principal object is returned
+    */
+   public Principal authenticate(SecurityRequestWrapper reqWrapper) {
+      String username;
+      String password;
+
+      String authData = reqWrapper.getParameter(AUTHENTICATION_DATA);
+
+      if (authData != null) {
+         String[] splitOutAuthData = authData.split(":");
+         if (splitOutAuthData != null && splitOutAuthData.length > 1) {
+            username = splitOutAuthData[0];
+            password = splitOutAuthData[1];
+         } else { // Invalid format
+            username = "";
+            password = "";
+         }
+      } else {
+         username = reqWrapper.getParameter(FORM_USERNAME);
+         password = reqWrapper.getParameter(FORM_PASSWORD);
+      }
+
+      if (booleanAuthenticate(username, password)) {
+         ArrayList roleList = new ArrayList();
+         roleList.add(Constants.VALID_ROLE);
+         return new SimplePrincipal(username);
+      }
+
+      return null;
+   }
+
+   /**
+    * Authenticate a user.
+    *
+    * Implement this method in a subclass to avoid dealing with Principal objects.
+    *
+    * @param username a username
+    * @param password a plain text password, as entered by the user
+    *
+    * @return null if the user cannot be authenticated, otherwise a Principal object is returned
+    */
+   public boolean booleanAuthenticate(String username, String password) {
+
+      return (
+         (Constants.VALID_USERNAME.equals(username) && Constants.VALID_PASSWORD.equals(password))
+         || (Constants.VALID_USERNAME2.equals(username) && Constants.VALID_PASSWORD2.equals(password))
+      );
+   }
+
+   /**
+    * Test for role membership.
+    *
+    * Implement this method in a subclass to avoid dealing with Principal objects.
+    *
+    * @param username The name of the user
+    * @param role name of a role to test for membership
+    * @return true if the user is in the role, false otherwise
+    */
+   public boolean isUserInRole(String username, String role) {
+      return (
+         (Constants.VALID_USERNAME.equals(username) || Constants.VALID_USERNAME2.equals(username))
+         && Constants.VALID_ROLE.equals(role)
+      );
+   }
+
+   /**
+    * Setter for exampleProperty to deomonstrate setting realm properties from config file.
+    *
+    * This has no effect other than printing a message when the property is set.
+    *
+    * @param value example property value
+    */
+   public void setExampleProperty(String value) {
+      exampleProperty = value;
+      System.out.println(this.getClass().getName() + ": exampleProperty set to \'" + value + "\'");
+   }
+
+   /**
+    * Getter for exampleProperty.
+    *
+    * @return the value of exampleProperty
+    */
+   public String getExampleProperty() {
+      return exampleProperty;
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
index f03f1fa..4c8f473 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator/FormAuthenticator.java,v 1.10 2004/01/26 10:55:21 maxcooper Exp $
- * $Revision: 1.10 $
- * $Date: 2004/01/26 10:55:21 $
+ * $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 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -59,6 +59,7 @@ import org.securityfilter.authenticator.persistent.PersistentLoginManagerInterfa
 import org.securityfilter.config.SecurityConfig;
 import org.securityfilter.filter.*;
 import org.securityfilter.realm.SecurityRealmInterface;
+import org.securityfilter.realm.FlexibleRealmInterface;
 
 import javax.servlet.FilterConfig;
 import javax.servlet.http.*;
@@ -69,7 +70,7 @@ import java.security.Principal;
  * FormAuthenticator - authenticator implementation for the FORM auth method.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.10 $ $Date: 2004/01/26 10:55:21 $
+ * @version $Revision: 1.11 $ $Date: 2005/02/22 11:02:16 $
  */
 public class FormAuthenticator implements Authenticator {
 
@@ -175,17 +176,22 @@ public class FormAuthenticator implements Authenticator {
       if (request.getMatchableURL().endsWith(loginSubmitPattern)) {
          String username = request.getParameter(FORM_USERNAME);
          String password = request.getParameter(FORM_PASSWORD);
-         Principal principal = realm.authenticate(username, 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 && !username.equals(request.getRemoteUser())) {
+            if (request.getUserPrincipal() != null
+                && false == request.getUserPrincipal().equals(principal)) {
                request.getSession().invalidate();
             }
 
             // manage persistent login info, if persistent login management is enabled
-            if (persistentLoginManager != null) {
+            // 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) {
@@ -202,9 +208,7 @@ public class FormAuthenticator implements Authenticator {
             // This is the url that the user was initially accessing before being prompted for login.
             response.sendRedirect(response.encodeRedirectURL(continueToURL));
          } else {
-            // login failed
-            // set response status and forward to error page
-            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+            // login failed - forward to error page
             request.getRequestDispatcher(errorPage).forward(request, response);
          }
          return true;
diff --git a/src/share/org/securityfilter/realm/FlexibleRealmInterface.java b/src/share/org/securityfilter/realm/FlexibleRealmInterface.java
new file mode 100644 (file)
index 0000000..a64a404
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/FlexibleRealmInterface.java,v 1.1 2005/02/22 11:02:27 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2005/02/22 11:02:27 $
+ *
+ * ====================================================================
+ * The SecurityFilter Software License, Version 1.1
+ *
+ * (this license is derived and fully compatible with the Apache Software
+ * License - see http://www.apache.org/LICENSE.txt)
+ *
+ * Copyright (c) 2002 SecurityFilter.org. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by
+ *        SecurityFilter.org (http://www.securityfilter.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "SecurityFilter" must not be used to endorse or promote
+ *    products derived from this software without prior written permission.
+ *    For written permission, please contact license@securityfilter.org .
+ *
+ * 5. Products derived from this software may not be called "SecurityFilter",
+ *    nor may "SecurityFilter" appear in their name, without prior written
+ *    permission of SecurityFilter.org.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE SECURITY FILTER PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ */
+
+package org.securityfilter.realm;
+
+import java.security.Principal;
+import org.securityfilter.filter.SecurityRequestWrapper;
+
+/**
+ * SecurityRealmInterface - realm interface for SecurityFilter. Implement this interface to provide
+ * a realm implementation against which SecurityFilter can authenticate and authortize users.
+ *
+ * Typically, a project will implement this interface or adapt an existing realm implementation to this interface.
+ *
+ * @author anonymous
+ * @version $Revision: 1.1 $ $Date: 2005/02/22 11:02:27 $
+ */
+public interface FlexibleRealmInterface extends SecurityRealmInterface {
+
+   /**
+    * Authenticate a user.
+    *
+    * @param credentials a wrapper around the user credentials
+    *
+    * @return a Principal object representing the user if successful, false otherwise
+    */
+   public Principal authenticate(SecurityRequestWrapper credentials);
+}
+
+// ------------------------------------------------------------------------
+// EOF
index a67cd15..915a3ce 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/TestBase.java,v 1.5 2003/06/14 14:11:44 maxcooper Exp $
- * $Revision: 1.5 $
- * $Date: 2003/06/14 14:11:44 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/TestBase.java,v 1.6 2005/02/22 11:02:29 maxcooper Exp $
+ * $Revision: 1.6 $
+ * $Date: 2005/02/22 11:02:29 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -59,11 +59,13 @@ import com.meterware.httpunit.*;
 import junit.framework.TestCase;
 import org.securityfilter.example.Constants;
 
+import javax.servlet.http.HttpServletResponse;
+
 /**
  * TestBase
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.5 $ $Date: 2003/06/14 14:11:44 $
+ * @version $Revision: 1.6 $ $Date: 2005/02/22 11:02:29 $
  */
 public class TestBase extends TestCase {
 
@@ -105,7 +107,10 @@ public class TestBase extends TestCase {
       WebResponse response = session.getResponse(request);
 
       // make sure the response leads us to login page
-      assertPageTitle(response, Constants.LOGIN_TITLE);
+      assertPageTitle(Constants.LOGIN_TITLE, response);
+
+      // make sure the response code is 200 for form-based login (see bugs 935921 & 1143612)
+      assertEquals(HttpServletResponse.SC_OK, response.getResponseCode());
 
       // submit valid login credentials
       WebForm loginForm = response.getFormWithID(Constants.LOGIN_FORM_ID);
@@ -121,9 +126,9 @@ public class TestBase extends TestCase {
     * @param pageTitle the expected page title
     * @throws Exception
     */
-   protected void assertPageTitleAfterLogin(String uri, String pageTitle) throws Exception {
+   protected void assertPageTitleAfterLogin(String pageTitle, String uri) throws Exception {
       WebResponse response = performJustInTimeLogin(uri);
-      assertPageTitle(response, pageTitle);
+      assertPageTitle(pageTitle, response);
    }
 
    /**
@@ -133,7 +138,7 @@ public class TestBase extends TestCase {
     * @param pageTitle the expected page title
     * @throws Exception
     */
-   protected void assertPageTitle(WebResponse response, String pageTitle) throws Exception {
+   protected void assertPageTitle(String pageTitle, WebResponse response) throws Exception {
       String title = response.getTitle();
       assertEquals(
          "Expected page title \"" + pageTitle + "\", got: \"" + title + "\"",
index 66a6aba..7a08295 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/CookiesDisabledTest.java,v 1.2 2004/01/26 09:32:33 maxcooper Exp $
- * $Revision: 1.2 $
- * $Date: 2004/01/26 09:32:33 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/CookiesDisabledTest.java,v 1.3 2005/02/22 11:02:37 maxcooper Exp $
+ * $Revision: 1.3 $
+ * $Date: 2005/02/22 11:02:37 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -62,7 +62,7 @@ import org.securityfilter.test.http.TestBase;
  * CookiesDisabledTest - Test that login behavior works with cookies disabled.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.2 $ $Date: 2004/01/26 09:32:33 $
+ * @version $Revision: 1.3 $ $Date: 2005/02/22 11:02:37 $
  */
 public class CookiesDisabledTest extends TestBase {
    /**
@@ -78,6 +78,6 @@ public class CookiesDisabledTest extends TestBase {
       // disable cookies
       session.getClientProperties().setAcceptCookies(false);
       // ensure that we get the secure page, loggin in on the way
-      assertPageTitleAfterLogin("/securePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/securePage.jsp");
    }
 }
index a2857aa..69fec65 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/DefaultPageTest.java,v 1.4 2003/10/25 10:17:01 maxcooper Exp $
- * $Revision: 1.4 $
- * $Date: 2003/10/25 10:17:01 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/DefaultPageTest.java,v 1.5 2005/02/22 11:02:52 maxcooper Exp $
+ * $Revision: 1.5 $
+ * $Date: 2005/02/22 11:02:52 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -63,7 +63,7 @@ import org.securityfilter.test.http.TestBase;
  * DefaultPageTest - tests that the user is sent to the default page on an "unsolicited" login.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.4 $ $Date: 2003/10/25 10:17:01 $
+ * @version $Revision: 1.5 $ $Date: 2005/02/22 11:02:52 $
  */
 public class DefaultPageTest extends TestBase {
    /**
@@ -94,7 +94,7 @@ public class DefaultPageTest extends TestBase {
       WebResponse response = session.getResponse(request);
 
       // make sure the response leads us to login page
-      assertPageTitle(response, Constants.LOGIN_TITLE);
+      assertPageTitle(Constants.LOGIN_TITLE, response);
 
       // submit valid login credentials
       WebForm loginForm = response.getFormWithID(Constants.LOGIN_FORM_ID);
@@ -103,7 +103,7 @@ public class DefaultPageTest extends TestBase {
       response = session.getResponse(loginForm.getRequest());
 
       // make sure the response leads to the default page (Home page -- index.jsp)
-      assertPageTitle(response, Constants.HOME_TITLE);
+      assertPageTitle(Constants.HOME_TITLE, response);
    }
 
    /**
@@ -125,6 +125,6 @@ public class DefaultPageTest extends TestBase {
       WebResponse response = session.getResponse(request);
 
       // make sure the response leads to the default page (Home page -- index.jsp)
-      assertPageTitle(response, Constants.HOME_TITLE);
+      assertPageTitle(Constants.HOME_TITLE, response);
    }
 }
index 0099135..0de1c70 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/JustInTimeTest.java,v 1.6 2003/06/14 14:11:44 maxcooper Exp $
- * $Revision: 1.6 $
- * $Date: 2003/06/14 14:11:44 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/JustInTimeTest.java,v 1.7 2005/02/22 11:02:58 maxcooper Exp $
+ * $Revision: 1.7 $
+ * $Date: 2005/02/22 11:02:58 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -62,7 +62,7 @@ import org.securityfilter.test.http.TestBase;
  * JustInTimeTest - This tests normal just-in-time login behavior.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.6 $ $Date: 2003/06/14 14:11:44 $
+ * @version $Revision: 1.7 $ $Date: 2005/02/22 11:02:58 $
  */
 public class JustInTimeTest extends TestBase {
    /**
@@ -80,7 +80,7 @@ public class JustInTimeTest extends TestBase {
     * @throws Exception
     */
    public void testJustInTime() throws Exception {
-      // ensure that we get the secure page, loggin in on the way
-      assertPageTitleAfterLogin("/securePage.jsp", Constants.SECURE_TITLE);
+      // ensure that we get the secure page, logging in on the way
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/securePage.jsp");
    }
 }
index c984c8e..3356daa 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/LogoutTest.java,v 1.2 2004/01/26 09:32:33 maxcooper Exp $
- * $Revision: 1.2 $
- * $Date: 2004/01/26 09:32:33 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/LogoutTest.java,v 1.3 2005/02/22 11:03:01 maxcooper Exp $
+ * $Revision: 1.3 $
+ * $Date: 2005/02/22 11:03:01 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -63,7 +63,7 @@ import org.securityfilter.test.http.TestBase;
  * LogoutTest - tests the logout functionality.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.2 $ $Date: 2004/01/26 09:32:33 $
+ * @version $Revision: 1.3 $ $Date: 2005/02/22 11:03:01 $
  */
 public class LogoutTest extends TestBase {
    /**
@@ -82,14 +82,14 @@ public class LogoutTest extends TestBase {
     */
    public void testLogout() throws Exception {
       // ensure that we get the secure page, loggin in on the way
-      assertPageTitleAfterLogin("/securePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/securePage.jsp");
 
       // logout
       WebRequest request = new GetMethodWebRequest(baseUrl + "/logout.jsp");
       WebResponse response = session.getResponse(request);
-      assertPageTitle(response, Constants.LOGOUT_TITLE);
+      assertPageTitle(Constants.LOGOUT_TITLE, response);
 
       // ensure that we get the secure page, loggin in on the way
-      assertPageTitleAfterLogin("/securePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/securePage.jsp");
    }
 }
index 5206ae6..55f1bc1 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/PathTricksTest.java,v 1.3 2003/06/10 12:11:26 maxcooper Exp $
- * $Revision: 1.3 $
- * $Date: 2003/06/10 12:11:26 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/PathTricksTest.java,v 1.4 2005/02/22 11:03:01 maxcooper Exp $
+ * $Revision: 1.4 $
+ * $Date: 2005/02/22 11:03:01 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -62,7 +62,7 @@ import org.securityfilter.test.http.TestBase;
  * PathTricksTest - tests for proper operation when "path tricks" are employed in URLs
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.3 $ $Date: 2003/06/10 12:11:26 $
+ * @version $Revision: 1.4 $ $Date: 2005/02/22 11:03:01 $
  */
 public class PathTricksTest extends TestBase {
    /**
@@ -81,7 +81,7 @@ public class PathTricksTest extends TestBase {
     */
    public void testSingleDotURLTrick() throws Exception {
       // request the secure page and login
-      assertPageTitleAfterLogin("/./securePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/./securePage.jsp");
    }
 
    /**
@@ -91,7 +91,7 @@ public class PathTricksTest extends TestBase {
     */
    public void testDoubleDotURLTrick() throws Exception {
       // request the secure page and login
-      assertPageTitleAfterLogin("/public/../securePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/public/../securePage.jsp");
    }
 
    /**
@@ -101,6 +101,6 @@ public class PathTricksTest extends TestBase {
     */
    public void testMultipleSlashURLTrick() throws Exception {
       // request the secure page and login
-      assertPageTitleAfterLogin("//securePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "//securePage.jsp");
    }
 }
index 3f8d9c2..5ad13dc 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/PostMethodTest.java,v 1.4 2003/10/25 10:49:03 maxcooper Exp $
- * $Revision: 1.4 $
- * $Date: 2003/10/25 10:49:03 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/PostMethodTest.java,v 1.5 2005/02/22 11:03:26 maxcooper Exp $
+ * $Revision: 1.5 $
+ * $Date: 2005/02/22 11:03:26 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -63,7 +63,7 @@ import org.securityfilter.test.http.TestBase;
  * PostMethodTest - tests that POSTed parameters are maintained through an authentication sequence.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.4 $ $Date: 2003/10/25 10:49:03 $
+ * @version $Revision: 1.5 $ $Date: 2005/02/22 11:03:26 $
  */
 public class PostMethodTest extends TestBase {
    private static final String POST_VALUE = "it works!";
@@ -92,7 +92,7 @@ public class PostMethodTest extends TestBase {
       response = sessionForm.submit();
 
       // make sure the response leads us to login page
-      assertPageTitle(response, Constants.LOGIN_TITLE);
+      assertPageTitle(Constants.LOGIN_TITLE, response);
 
       // submit valid login credentials
       WebForm loginForm = response.getFormWithID(Constants.LOGIN_FORM_ID);
@@ -101,12 +101,12 @@ public class PostMethodTest extends TestBase {
       response = session.getResponse(loginForm.getRequest());
 
       // make sure the response leads us to secure page
-      assertPageTitle(response, Constants.SECURE_TITLE);
+      assertPageTitle(Constants.SECURE_TITLE, response);
 
       // make sure the item we submitted is present
       WebForm form = response.getFormWithName(Constants.SECURE_POSTED_VALUE_FORM);
       String postedValue = form.getParameterValue(Constants.SECURE_POSTED_VALUE_FIELD);
       assertNotNull("POSTed parameter not found in reponse", postedValue);
-      assertEquals("POSTed parameter did not have the right value", postedValue, POST_VALUE);
+      assertEquals("POSTed parameter did not have the right value", POST_VALUE, postedValue);
    }
 }
index 5512e8f..5f033b8 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/SessionInvalidationTest.java,v 1.1 2003/10/25 10:49:03 maxcooper Exp $
- * $Revision: 1.1 $
- * $Date: 2003/10/25 10:49:03 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/SessionInvalidationTest.java,v 1.2 2005/02/22 11:03:26 maxcooper Exp $
+ * $Revision: 1.2 $
+ * $Date: 2005/02/22 11:03:26 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -63,7 +63,7 @@ import org.securityfilter.test.http.TestBase;
  * SessionInvalidationTest - tests the logout functionality.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.1 $ $Date: 2003/10/25 10:49:03 $
+ * @version $Revision: 1.2 $ $Date: 2005/02/22 11:03:26 $
  */
 public class SessionInvalidationTest extends TestBase {
    private static final String POST_VALUE_1 = "post1";
@@ -113,16 +113,16 @@ public class SessionInvalidationTest extends TestBase {
       response = sessionForm.submit();
 
       // make sure the response leads us to secure page
-      assertPageTitle(response, Constants.SECURE_TITLE);
+      assertPageTitle(Constants.SECURE_TITLE, response);
 
       // ensure that both the first and second POSTed values appear on the secure page
       WebForm form = response.getFormWithName(Constants.SECURE_POSTED_VALUE_FORM);
       String firstPostedValue = form.getParameterValue(Constants.SECURE_LAST_POSTED_VALUE_FIELD);
       assertNotNull("First POSTed parameter not found in reponse", firstPostedValue);
-      assertEquals("First POSTed parameter did not have the right value", firstPostedValue, POST_VALUE_1);
+      assertEquals("First POSTed parameter did not have the right value", POST_VALUE_1, firstPostedValue);
       String secondPostedValue = form.getParameterValue(Constants.SECURE_POSTED_VALUE_FIELD);
       assertNotNull("Second POSTed parameter not found in reponse", secondPostedValue);
-      assertEquals("Second POSTed parameter did not have the right value", secondPostedValue, POST_VALUE_2);
+      assertEquals("Second POSTed parameter did not have the right value", POST_VALUE_2, secondPostedValue);
    }
 
    /**
@@ -160,7 +160,7 @@ public class SessionInvalidationTest extends TestBase {
       response = sessionForm.submit();
 
       // make sure the response leads us to secure page
-      assertPageTitle(response, Constants.SECURE_TITLE);
+      assertPageTitle(Constants.SECURE_TITLE, response);
 
       // ensure that both the first and second POSTed values appear on the secure page
       WebForm form = response.getFormWithName(Constants.SECURE_POSTED_VALUE_FORM);
@@ -168,6 +168,6 @@ public class SessionInvalidationTest extends TestBase {
       assertNull("First POSTed parameter found in response, but it shouldn't be there", firstPostedValue);
       String secondPostedValue = form.getParameterValue(Constants.SECURE_POSTED_VALUE_FIELD);
       assertNotNull("Second POSTed parameter not found in reponse", secondPostedValue);
-      assertEquals("Second POSTed parameter did not have the right value", secondPostedValue, POST_VALUE_2);
+      assertEquals("Second POSTed parameter did not have the right value", POST_VALUE_2, secondPostedValue);
    }
 }
index bbd3be8..b72a5a8 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/UTFTest.java,v 1.2 2003/06/10 12:11:26 maxcooper Exp $
- * $Revision: 1.2 $
- * $Date: 2003/06/10 12:11:26 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/test/org/securityfilter/test/http/form/UTFTest.java,v 1.3 2005/02/22 11:03:26 maxcooper Exp $
+ * $Revision: 1.3 $
+ * $Date: 2005/02/22 11:03:26 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -63,7 +63,7 @@ import org.securityfilter.test.http.TestBase;
  * are used. Failures would indicate a security vulnerability.
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.2 $ $Date: 2003/06/10 12:11:26 $
+ * @version $Revision: 1.3 $ $Date: 2005/02/22 11:03:26 $
  */
 public class UTFTest extends TestBase {
    /**
@@ -83,7 +83,7 @@ public class UTFTest extends TestBase {
     */
    public void testUTFEncodedDirectorySeparator() throws Exception {
       // request the secure page and login
-      assertPageTitleAfterLogin("%2FsecurePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "%2FsecurePage.jsp");
    }
 
    /**
@@ -94,6 +94,6 @@ public class UTFTest extends TestBase {
     */
    public void testUTFEncodedPageName() throws Exception {
       // request the secure page and login
-      assertPageTitleAfterLogin("/%73ecurePage.jsp", Constants.SECURE_TITLE);
+      assertPageTitleAfterLogin(Constants.SECURE_TITLE, "/%73ecurePage.jsp");
    }
 }