Explorar o código

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 %!s(int64=21) %!d(string=hai) anos
pai
achega
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