Browse Source

Enhance AuthenticationProcessingFilterEntryPoint and related classes, to support a property forcing the login page to be access via https even if the original intercepted request came in as http.

Colin Sampaleanu 21 năm trước cách đây
mục cha
commit
e2de3c9dbc

+ 6 - 5
core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java

@@ -320,21 +320,22 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
                     logger.debug("Switching to RunAs Authentication: "
                         + runAs.toString());
                 }
-                
+
                 SecureContext origSecureContext = null;
+
                 try {
-                    origSecureContext = (SecureContext) ContextHolder.getContext();
+                    origSecureContext = (SecureContext) ContextHolder
+                        .getContext();
                     context.setAuthentication(runAs);
                     ContextHolder.setContext((Context) context);
 
                     return callback.proceedWithObject(object);
-                }
-                finally {
+                } finally {
                     if (logger.isDebugEnabled()) {
                         logger.debug("Reverting to original Authentication: "
                             + authenticated.toString());
                     }
-                    
+
                     origSecureContext.setAuthentication(authenticated);
                     ContextHolder.setContext(origSecureContext);
                 }

+ 8 - 0
core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java

@@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletResponse;
  * </p>
  *
  * @author Ben Alex
+ * @author colin sampaleanu
  * @version $Id$
  */
 public class FilterInvocation {
@@ -80,6 +81,13 @@ public class FilterInvocation {
         return chain;
     }
 
+    public String getFullRequestUrl() {
+        return getHttpRequest().getRequestURL().toString()
+        + ((getHttpRequest().getQueryString() == null) ? ""
+                                                       : ("?"
+        + getHttpRequest().getQueryString()));
+    }
+
     public HttpServletRequest getHttpRequest() {
         return (HttpServletRequest) request;
     }

+ 2 - 2
core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java

@@ -154,11 +154,11 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean {
             if (logger.isDebugEnabled()) {
                 logger.debug(
                     "Authentication failed - adding target URL to Session: "
-                    + fi.getRequestUrl());
+                    + fi.getFullRequestUrl());
             }
 
             ((HttpServletRequest) request).getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY,
-                fi.getRequestUrl());
+                fi.getFullRequestUrl());
             authenticationEntryPoint.commence(request, response);
         } catch (AccessDeniedException accessDenied) {
             if (logger.isDebugEnabled()) {

+ 2 - 1
core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java

@@ -155,7 +155,8 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
         }
 
         // Ensure credentials are presented
-        if (authentication.getCredentials() == null || "".equals(authentication.getCredentials())) {
+        if ((authentication.getCredentials() == null)
+            || "".equals(authentication.getCredentials())) {
             throw new BadCredentialsException(
                 "Failed to provide a CAS service ticket to validate");
         }

+ 3 - 1
core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java

@@ -19,6 +19,7 @@ import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.providers.AbstractAuthenticationToken;
 
 import java.io.Serializable;
+
 import java.util.List;
 
 
@@ -28,7 +29,8 @@ import java.util.List;
  * @author Ben Alex
  * @version $Id$
  */
-public class CasAuthenticationToken extends AbstractAuthenticationToken implements Serializable {
+public class CasAuthenticationToken extends AbstractAuthenticationToken
+    implements Serializable {
     //~ Instance fields ========================================================
 
     private List proxyList;

+ 6 - 3
core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java

@@ -63,7 +63,9 @@ import javax.servlet.http.HttpServletResponse;
  * <code>defaultTargetUrl</code> indicates the URL that should be used for
  * redirection if the <code>HttpSession</code> attribute named {@link
  * #ACEGI_SECURITY_TARGET_URL_KEY} does not indicate the target URL once
- * authentication is completed successfully. eg: <code>/</code>.
+ * authentication is completed successfully. eg: <code>/</code>. This will be
+ * treated as relative to the web-app's context path, and should include the
+ * leading <code>/</code>.
  * </li>
  * <li>
  * <code>authenticationFailureUrl</code> indicates the URL that should be used
@@ -78,6 +80,7 @@ import javax.servlet.http.HttpServletResponse;
  * 
  *
  * @author Ben Alex
+ * @author colin sampaleanu
  * @version $Id$
  */
 public abstract class AbstractProcessingFilter implements Filter,
@@ -240,7 +243,7 @@ public abstract class AbstractProcessingFilter implements Filter,
                 null);
 
             if (targetUrl == null) {
-                targetUrl = defaultTargetUrl;
+                targetUrl = httpRequest.getContextPath() + defaultTargetUrl;
             }
 
             if (logger.isDebugEnabled()) {
@@ -249,7 +252,7 @@ public abstract class AbstractProcessingFilter implements Filter,
                     + targetUrl);
             }
 
-            httpResponse.sendRedirect(httpRequest.getContextPath() + targetUrl);
+            httpResponse.sendRedirect(targetUrl);
 
             return;
         }

+ 1 - 1
core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java

@@ -97,7 +97,7 @@ public class CasProcessingFilter extends AbstractProcessingFilter {
         String username = CAS_STATEFUL_IDENTIFIER;
         String password = request.getParameter("ticket");
 
-         if (password == null) {
+        if (password == null) {
             password = "";
         }
 

+ 17 - 14
core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java

@@ -35,8 +35,7 @@ public class ServiceProperties implements InitializingBean {
     //~ Instance fields ========================================================
 
     private String service;
-
-     private boolean sendRenew = false;
+    private boolean sendRenew = false;
 
     //~ Methods ================================================================
 
@@ -47,12 +46,15 @@ public class ServiceProperties implements InitializingBean {
     /**
      * Indicates whether the <code>renew</code> parameter should be sent to the
      * CAS login URL and CAS validation URL.
-     * <P> If <code>true</code>, it will
-     * force CAS to authenticate the user again (even if the user has
-     * previously authenticated). During ticket validation it will require the
-     * ticket was generated as a consequence of an explicit login. High
-     * security applications would probably set this to <code>true</code>.
-     * Defaults to <code>false</code>, providing automated single sign on.
+     * 
+     * <p>
+     * If <code>true</code>, it will force CAS to authenticate the user again
+     * (even if the user has previously authenticated). During ticket
+     * validation it will require the ticket was generated as a consequence of
+     * an explicit login. High security applications would probably set this
+     * to <code>true</code>. Defaults to <code>false</code>, providing
+     * automated single sign on.
+     * </p>
      *
      * @return whether to send the <code>renew</code> parameter to CAS
      */
@@ -65,13 +67,14 @@ public class ServiceProperties implements InitializingBean {
     }
 
     /**
-      * Represents the service the user is authenticating to. 
-      * 
-      * <B>This service is the callback URL
-     * belonging to the local Acegi Security System for Spring secured
-     * application. For example,
+     * Represents the service the user is authenticating to.
+     * 
+     * <p>
+     * This service is the callback URL belonging to the local Acegi Security
+     * System for Spring secured application. For example,
+     * </p>
      * <code>https://www.mycompany.com/application/j_acegi_cas_security_check</code>
-    * 
+     *
      * @return the URL of the service the user is authenticating to
      */
     public String getService() {

+ 123 - 55
core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java

@@ -20,6 +20,7 @@ import net.sf.acegisecurity.intercept.web.AuthenticationEntryPoint;
 import org.springframework.beans.factory.InitializingBean;
 
 import java.io.IOException;
+
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -32,8 +33,31 @@ import javax.servlet.http.HttpServletResponse;
 
 
 /**
+ * <p>
  * Used by the <code>SecurityEnforcementFilter</code> to commence
- * authentication via the {@link AuthenticationProcessingFilter}.
+ * authentication via the {@link AuthenticationProcessingFilter}. This object
+ * holds the location of the login form, relative to the web app context path,
+ * and is used to commence a redirect to that form.
+ * </p>
+ * 
+ * <p>
+ * By setting the <em>forceHttps</em> property to true, you may configure the
+ * class to force the protocol used for the login form to be
+ * <code>https</code>, even if the original intercepted request for a resource
+ * used the <code>http</code> protocol. When this happens, after a successful
+ * login (via https), the original resource will still be accessed as http,
+ * via the original request URL. For the forced https feature to work, the
+ * class must have a valid mapping from an http port in the original request
+ * to an https port for the login page (the same server name will be used,
+ * only the scheme and port will be changed). By default, http requests to
+ * port 80 will be mapped to login page https requests on port 443 (standard
+ * https port), and port 8080 will be mapped to port 8443. These mappings may
+ * be customized by setting the <em>httpsPortMappings</em> property. Any
+ * intercepted http request on a port which does not have a mapping will
+ * result in the protocol remaining as http. Any intercepted request which is
+ * already https will always result in the login page being accessed as https,
+ * regardless of the state of the  <em>forceHttps</em> property.
+ * </p>
  *
  * @author Ben Alex
  * @author colin sampaleanu
@@ -43,24 +67,95 @@ public class AuthenticationProcessingFilterEntryPoint
     implements AuthenticationEntryPoint, InitializingBean {
     //~ Instance fields ========================================================
 
-    /**
-     * The URL where the <code>AuthenticationProcessingFilter</code> login page
-     * can be found.
-     */
+    private HashMap httpsPortMappings;
     private String loginFormUrl;
-    
     private boolean forceHttps = false;
-    
-    private HashMap httpsPortMapping;
 
-    //~ Methods ================================================================
-    
+    //~ Constructors ===========================================================
+
     public AuthenticationProcessingFilterEntryPoint() {
-        httpsPortMapping = new HashMap();
-        httpsPortMapping.put(new Integer(80), new Integer(443));
-        httpsPortMapping.put(new Integer(8080), new Integer(8443));
+        httpsPortMappings = new HashMap();
+        httpsPortMappings.put(new Integer(80), new Integer(443));
+        httpsPortMappings.put(new Integer(8080), new Integer(8443));
+    }
+
+    //~ Methods ================================================================
+
+    /**
+     * Set to true to force login form access to be via https. If this value is
+     * ture (the default is false), and the incoming request for the protected
+     * resource which triggered the interceptor was not already
+     * <code>https</code>, then
+     *
+     * @param forceHttps
+     *
+     * @todo Generated comment
+     */
+    public void setForceHttps(boolean forceHttps) {
+        this.forceHttps = forceHttps;
+    }
+
+    public boolean getForceHttps() {
+        return forceHttps;
     }
 
+    /**
+     * <p>
+     * Set to override the default http port to https port mappings of 80:443,
+     * and  8080:8443.
+     * </p>
+     * In a Spring XML ApplicationContext, a definition would look something
+     * like this:
+     * <pre>
+     *   &lt;property name="httpsPortMapping">
+     *     &lt;map>
+     *       &lt;entry key="80">&lt;value>443&lt;/value>&lt;/entry>
+     *       &lt;entry key="8080">&lt;value>8443&lt;/value>&lt;/entry>
+     *     &lt;/map>
+     *   &lt;/property>
+     * </pre>
+     *
+     * @param newMappings A Map consisting of String keys and String values,
+     *        where for each entry the key is the string representation of an
+     *        integer http port number, and the value is the string
+     *        representation of the corresponding integer https port number.
+     *
+     * @throws IllegalArgumentException if input map does not consist of String
+     *         keys and values, each representing an integer port number in
+     *         the range 1-65535 for that mapping.
+     */
+    public void setHttpsPortMappings(HashMap newMappings) {
+        httpsPortMappings.clear();
+
+        Iterator it = newMappings.entrySet().iterator();
+
+        while (it.hasNext()) {
+            Map.Entry entry = (Map.Entry) it.next();
+            Integer httpPort = new Integer((String) entry.getKey());
+            Integer httpsPort = new Integer((String) entry.getValue());
+
+            if ((httpPort.intValue() < 1) || (httpPort.intValue() > 65535)
+                || (httpsPort.intValue() < 1) || (httpsPort.intValue() > 65535)) {
+                throw new IllegalArgumentException(
+                    "one or both ports out of legal range: " + httpPort + ", "
+                    + httpsPort);
+            }
+
+            httpsPortMappings.put(httpPort, httpsPort);
+
+            if (httpsPortMappings.size() < 1) {
+                throw new IllegalArgumentException("must map at least one port");
+            }
+        }
+    }
+
+    /**
+     * The URL where the <code>AuthenticationProcessingFilter</code> login page
+     * can be found. Should be relative to the web-app context path, and
+     * include a leading <code>/</code>
+     *
+     * @param loginFormUrl
+     */
     public void setLoginFormUrl(String loginFormUrl) {
         this.loginFormUrl = loginFormUrl;
     }
@@ -77,59 +172,32 @@ public class AuthenticationProcessingFilterEntryPoint
 
     public void commence(ServletRequest request, ServletResponse response)
         throws IOException, ServletException {
-        
         HttpServletRequest req = (HttpServletRequest) request;
-        String contextPath = req.getContextPath(); 
-        
-        String redirectUrl =  contextPath + loginFormUrl;
-        
+        String contextPath = req.getContextPath();
+
+        String redirectUrl = contextPath + loginFormUrl;
+
         if (forceHttps && req.getScheme().equals("http")) {
             Integer httpPort = new Integer(req.getServerPort());
-            Integer httpsPort = (Integer) httpsPortMapping.get(httpPort);
-            if (httpsPort != null ) {
+            Integer httpsPort = (Integer) httpsPortMappings.get(httpPort);
+
+            if (httpsPort != null) {
                 String serverName = req.getServerName();
-                redirectUrl = "https://" + serverName + ":" + httpsPort + contextPath
-                        + loginFormUrl;
+                redirectUrl = "https://" + serverName + ":" + httpsPort
+                    + contextPath + loginFormUrl;
             }
         }
-        
+
         ((HttpServletResponse) response).sendRedirect(redirectUrl);
     }
-    
-    public void setForceHttps(boolean forceSsl) {
-        this.forceHttps = forceSsl;
-    }
-    public boolean getForceHttps() {
-        return forceHttps;
-    }
 
-    /**
-     * @throws IllegalArgumentException if input map does not consist of String keys
-     * and values, each representing an integer port number for one mapping.
-     */
-    public void setHttpsPortMapping(HashMap newMappings) {
-        httpsPortMapping.clear();
-        Iterator it = newMappings.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry entry = (Map.Entry) it.next();
-            Integer httpPort = new Integer((String)entry.getKey());
-            Integer httpsPort = new Integer((String)entry.getValue());
-            if (httpPort.intValue() < 1 || httpPort.intValue() > 65535 ||
-                    httpsPort.intValue() < 1 || httpsPort.intValue() > 65535)
-                throw new IllegalArgumentException("one or both ports out of legal range: "
-                        + httpPort + ", " + httpsPort);
-            httpsPortMapping.put(httpPort, httpsPort);
-            if (httpsPortMapping.size() < 1)
-                throw new IllegalArgumentException("must map at least one port");
-        }
-        
-    }
-    
     /**
      * Returns the translated (Integer -> Integer) version of the original port
-     * mapping specified via setHttpsPortMapping() 
+     * mapping specified via setHttpsPortMapping()
+     *
+     * @return DOCUMENT ME!
      */
-    protected HashMap getTranslatedHttpsPortMapping() {
-        return httpsPortMapping;
+    protected HashMap getTranslatedHttpsPortMappings() {
+        return httpsPortMappings;
     }
 }

+ 2 - 2
core/src/main/java/org/acegisecurity/userdetails/User.java

@@ -15,10 +15,10 @@
 
 package net.sf.acegisecurity.providers.dao;
 
-import java.io.Serializable;
-
 import net.sf.acegisecurity.GrantedAuthority;
 
+import java.io.Serializable;
+
 
 /**
  * Models core user information retieved by an {@link AuthenticationDao}.

+ 25 - 4
core/src/test/java/org/acegisecurity/MockHttpServletRequest.java

@@ -42,6 +42,7 @@ import javax.servlet.http.HttpSession;
  * </p>
  *
  * @author Ben Alex
+ * @author colin sampaleanu
  * @version $Id$
  */
 public class MockHttpServletRequest implements HttpServletRequest {
@@ -53,7 +54,11 @@ public class MockHttpServletRequest implements HttpServletRequest {
     private Principal principal;
     private String contextPath = "";
     private String queryString = null;
+    private String requestURL;
+    private String scheme;
+    private String serverName;
     private String servletPath;
+    private int serverPort;
 
     //~ Constructors ===========================================================
 
@@ -235,8 +240,12 @@ public class MockHttpServletRequest implements HttpServletRequest {
         throw new UnsupportedOperationException("mock method not implemented");
     }
 
+    public void setRequestURL(String newRequestURL) {
+        requestURL = newRequestURL;
+    }
+
     public StringBuffer getRequestURL() {
-        throw new UnsupportedOperationException("mock method not implemented");
+        return new StringBuffer(requestURL);
     }
 
     public String getRequestedSessionId() {
@@ -259,20 +268,32 @@ public class MockHttpServletRequest implements HttpServletRequest {
         throw new UnsupportedOperationException("mock method not implemented");
     }
 
+    public void setScheme(String newScheme) {
+        scheme = newScheme;
+    }
+
     public String getScheme() {
-        throw new UnsupportedOperationException("mock method not implemented");
+        return scheme;
     }
 
     public boolean isSecure() {
         throw new UnsupportedOperationException("mock method not implemented");
     }
 
+    public void setServerName(String newServerName) {
+        serverName = newServerName;
+    }
+
     public String getServerName() {
-        throw new UnsupportedOperationException("mock method not implemented");
+        return serverName;
+    }
+
+    public void setServerPort(int newPort) {
+        serverPort = newPort;
     }
 
     public int getServerPort() {
-        throw new UnsupportedOperationException("mock method not implemented");
+        return serverPort;
     }
 
     public void setServletPath(String servletPath) {

+ 10 - 0
core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java

@@ -41,6 +41,7 @@ import javax.servlet.ServletResponse;
  * Tests {@link FilterInvocation}.
  *
  * @author Ben Alex
+ * @author colin sampaleanu
  * @version $Id$
  */
 public class FilterInvocationTests extends TestCase {
@@ -67,6 +68,7 @@ public class FilterInvocationTests extends TestCase {
     public void testGettersAndStringMethods() {
         MockHttpServletRequest request = new MockHttpServletRequest(null, null);
         request.setServletPath("/HelloWorld");
+        request.setRequestURL("http://www.example.com/mycontext/HelloWorld");
 
         MockHttpServletResponse response = new MockHttpServletResponse();
         MockFilterChain chain = new MockFilterChain();
@@ -78,6 +80,8 @@ public class FilterInvocationTests extends TestCase {
         assertEquals(chain, fi.getChain());
         assertEquals("/HelloWorld", fi.getRequestUrl());
         assertEquals("FilterInvocation: URL: /HelloWorld", fi.toString());
+        assertEquals("http://www.example.com/mycontext/HelloWorld",
+            fi.getFullRequestUrl());
     }
 
     public void testNoArgsConstructor() {
@@ -156,23 +160,29 @@ public class FilterInvocationTests extends TestCase {
     public void testStringMethodsWithAQueryString() {
         MockHttpServletRequest request = new MockHttpServletRequest("foo=bar");
         request.setServletPath("/HelloWorld");
+        request.setRequestURL("http://www.example.com/mycontext/HelloWorld");
 
         MockHttpServletResponse response = new MockHttpServletResponse();
         MockFilterChain chain = new MockFilterChain();
         FilterInvocation fi = new FilterInvocation(request, response, chain);
         assertEquals("/HelloWorld?foo=bar", fi.getRequestUrl());
         assertEquals("FilterInvocation: URL: /HelloWorld?foo=bar", fi.toString());
+        assertEquals("http://www.example.com/mycontext/HelloWorld?foo=bar",
+            fi.getFullRequestUrl());
     }
 
     public void testStringMethodsWithoutAnyQueryString() {
         MockHttpServletRequest request = new MockHttpServletRequest(null, null);
         request.setServletPath("/HelloWorld");
+        request.setRequestURL("http://www.example.com/mycontext/HelloWorld");
 
         MockHttpServletResponse response = new MockHttpServletResponse();
         MockFilterChain chain = new MockFilterChain();
         FilterInvocation fi = new FilterInvocation(request, response, chain);
         assertEquals("/HelloWorld", fi.getRequestUrl());
         assertEquals("FilterInvocation: URL: /HelloWorld", fi.toString());
+        assertEquals("http://www.example.com/mycontext/HelloWorld",
+            fi.getFullRequestUrl());
     }
 
     //~ Inner Classes ==========================================================

+ 3 - 1
core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java

@@ -128,6 +128,8 @@ public class SecurityEnforcementFilterTests extends TestCase {
         MockHttpServletRequest request = new MockHttpServletRequest(null,
                 new MockHttpSession());
         request.setServletPath("/secure/page.html");
+        request.setRequestURL(
+            "http://www.example.com/mycontext/secure/page.html");
 
         // Setup our expectation that the filter chain will not be invoked, as access is denied
         MockFilterChain chain = new MockFilterChain(false);
@@ -146,7 +148,7 @@ public class SecurityEnforcementFilterTests extends TestCase {
         MockHttpServletResponse response = new MockHttpServletResponse();
         filter.doFilter(request, response, chain);
         assertEquals("/login.jsp", response.getRedirect());
-        assertEquals("/secure/page.html",
+        assertEquals("http://www.example.com/mycontext/secure/page.html",
             request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY));
     }
 

+ 1 - 1
core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java

@@ -65,7 +65,7 @@ public class ServicePropertiesTests extends TestCase {
 
         sp.setService("https://mycompany.com/service");
         assertEquals("https://mycompany.com/service", sp.getService());
-        
+
         sp.afterPropertiesSet();
     }
 }

+ 74 - 35
core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java

@@ -15,22 +15,22 @@
 
 package net.sf.acegisecurity.ui.webapp;
 
-import java.util.HashMap;
-
 import junit.framework.TestCase;
 
 import net.sf.acegisecurity.MockHttpServletRequest;
 import net.sf.acegisecurity.MockHttpServletResponse;
 
+import java.util.HashMap;
+
 
 /**
  * Tests {@link AuthenticationProcessingFilterEntryPoint}.
  *
  * @author Ben Alex
+ * @author colin sampaleanu
  * @version $Id$
  */
 public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
-
     //~ Methods ================================================================
 
     public final void setUp() throws Exception {
@@ -57,58 +57,97 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
         ep.setLoginFormUrl("/hello");
         assertEquals("/hello", ep.getLoginFormUrl());
     }
-    
+
+    public void testHttpsOperation() throws Exception {
+        MockHttpServletRequest request = new MockHttpServletRequest(
+                "/some_path");
+        request.setScheme("http");
+        request.setServerName("www.example.com");
+        request.setContextPath("/bigWebApp");
+        request.setServerPort(80);
+
+        MockHttpServletResponse response = new MockHttpServletResponse();
+
+        AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+        ep.setLoginFormUrl("/hello");
+        ep.setForceHttps(true);
+        ep.afterPropertiesSet();
+
+        ep.commence(request, response);
+        assertEquals("https://www.example.com:443/bigWebApp/hello",
+            response.getRedirect());
+
+        request.setServerPort(8080);
+        ep.commence(request, response);
+        assertEquals("https://www.example.com:8443/bigWebApp/hello",
+            response.getRedirect());
+
+        // check that unknown port leaves things as-is
+        request.setServerPort(8888);
+        ep.commence(request, response);
+        assertEquals("/bigWebApp/hello", response.getRedirect());
+
+        ep = new AuthenticationProcessingFilterEntryPoint();
+        ep.setLoginFormUrl("/hello");
+        ep.setForceHttps(true);
+
+        HashMap map = new HashMap();
+        map.put("8888", "9999");
+        ep.setHttpsPortMappings(map);
+        ep.afterPropertiesSet();
+
+        ep.commence(request, response);
+        assertEquals("https://www.example.com:9999/bigWebApp/hello",
+            response.getRedirect());
+    }
+
+    public void testNormalOperation() throws Exception {
+        AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+        ep.setLoginFormUrl("/hello");
+
+        MockHttpServletRequest request = new MockHttpServletRequest(
+                "/some_path");
+        request.setContextPath("/bigWebApp");
+
+        MockHttpServletResponse response = new MockHttpServletResponse();
+
+        ep.afterPropertiesSet();
+        ep.commence(request, response);
+        assertEquals("/bigWebApp/hello", response.getRedirect());
+    }
+
     public void testSetSslPortMapping() {
         AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
         HashMap map = new HashMap();
+
         try {
-            ep.setHttpsPortMapping(map);
+            ep.setHttpsPortMappings(map);
         } catch (IllegalArgumentException expected) {
             assertEquals("must map at least one port", expected.getMessage());
         }
-        
+
         map.put(new Integer(0).toString(), new Integer(443).toString());
+
         try {
-            ep.setHttpsPortMapping(map);
+            ep.setHttpsPortMappings(map);
         } catch (IllegalArgumentException expected) {
             assertTrue(expected.getMessage().startsWith("one or both ports out of legal range"));
         }
-        
+
         map.clear();
         map.put(new Integer(80).toString(), new Integer(100000).toString());
+
         try {
-            ep.setHttpsPortMapping(map);
+            ep.setHttpsPortMappings(map);
         } catch (IllegalArgumentException expected) {
             assertTrue(expected.getMessage().startsWith("one or both ports out of legal range"));
         }
-        
+
         map.clear();
         map.put(new Integer(80).toString(), new Integer(443).toString());
-        ep.setHttpsPortMapping(map);
-        map = ep.getTranslatedHttpsPortMapping();
+        ep.setHttpsPortMappings(map);
+        map = ep.getTranslatedHttpsPortMappings();
         assertTrue(map.size() == 1);
-        assertTrue(((Integer)map.get(new Integer(80))).equals(new Integer(443)));
-    }
-
-    public void testNormalOperation() throws Exception {
-        AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
-        ep.setLoginFormUrl("/hello");
-
-        MockHttpServletRequest request = new MockHttpServletRequest(
-                "/some_path");
-        request.setContextPath("/bigWebApp");
-
-        MockHttpServletResponse response = new MockHttpServletResponse();
-
-        ep.afterPropertiesSet();
-        ep.commence(request, response);
-        assertEquals("/bigWebApp/hello", response.getRedirect());
-    }
-    
-    public void testHttpsOperation() throws Exception {
-        AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
-        
-        //TODO: finish later today
+        assertTrue(((Integer) map.get(new Integer(80))).equals(new Integer(443)));
     }
-    
 }

+ 1 - 1
test/acegisecuritytest.properties

@@ -1,5 +1,5 @@
 #HSQL database
-#Fri Apr 16 07:51:49 EDT 2004
+#Thu Apr 22 17:27:10 EDT 2004
 sql.strict_fk=true
 readonly=false
 sql.strong_fk=true