فهرست منبع

SEC-174: Correct IE6 bug with AuthenticationProcessingFilterEntryPoint.

Ben Alex 19 سال پیش
والد
کامیت
3a01e48b17

+ 67 - 56
core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -12,10 +12,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.acegisecurity.ui.webapp;
 
 import org.acegisecurity.AuthenticationException;
+
 import org.acegisecurity.ui.AuthenticationEntryPoint;
+
 import org.acegisecurity.util.PortMapper;
 import org.acegisecurity.util.PortMapperImpl;
 import org.acegisecurity.util.PortResolver;
@@ -44,7 +47,7 @@ import javax.servlet.http.HttpServletResponse;
  * 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
@@ -62,58 +65,18 @@ import javax.servlet.http.HttpServletResponse;
  */
 public class AuthenticationProcessingFilterEntryPoint
     implements AuthenticationEntryPoint, InitializingBean {
+    //~ Static fields/initializers =============================================
+
     private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class);
+
+    //~ Instance fields ========================================================
+
     private PortMapper portMapper = new PortMapperImpl();
     private PortResolver portResolver = new PortResolverImpl();
     private String loginFormUrl;
     private boolean forceHttps = false;
 
-    /**
-     * 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
-     */
-    public void setForceHttps(boolean forceHttps) {
-        this.forceHttps = forceHttps;
-    }
-
-    public boolean getForceHttps() {
-        return forceHttps;
-    }
-
-    /**
-     * 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;
-    }
-
-    public String getLoginFormUrl() {
-        return loginFormUrl;
-    }
-
-    public void setPortMapper(PortMapper portMapper) {
-        this.portMapper = portMapper;
-    }
-
-    public PortMapper getPortMapper() {
-        return portMapper;
-    }
-
-    public void setPortResolver(PortResolver portResolver) {
-        this.portResolver = portResolver;
-    }
-
-    public PortResolver getPortResolver() {
-        return portResolver;
-    }
+    //~ Methods ================================================================
 
     public void afterPropertiesSet() throws Exception {
         Assert.hasLength(loginFormUrl, "loginFormUrl must be specified");
@@ -133,8 +96,7 @@ public class AuthenticationProcessingFilterEntryPoint
         boolean inHttp = "http".equals(scheme.toLowerCase());
         boolean inHttps = "https".equals(scheme.toLowerCase());
 
-        boolean includePort = ((inHttp && (serverPort == 80)) ||
-            (inHttps && (serverPort == 443)));
+        boolean includePort = true;
 
         if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) {
             includePort = false;
@@ -144,7 +106,9 @@ public class AuthenticationProcessingFilterEntryPoint
             includePort = false;
         }
 
-        String redirectUrl = contextPath + loginFormUrl;
+        String redirectUrl = scheme + "://" + serverName
+            + ((includePort) ? (":" + serverPort) : "") + contextPath
+            + loginFormUrl;
 
         if (forceHttps && inHttp) {
             Integer httpPort = new Integer(portResolver.getServerPort(request));
@@ -157,9 +121,9 @@ public class AuthenticationProcessingFilterEntryPoint
                     includePort = true;
                 }
 
-                redirectUrl = "https://" + serverName +
-                    ((includePort) ? (":" + httpsPort) : "") + contextPath +
-                    loginFormUrl;
+                redirectUrl = "https://" + serverName
+                    + ((includePort) ? (":" + httpsPort) : "") + contextPath
+                    + loginFormUrl;
             }
         }
 
@@ -167,7 +131,54 @@ public class AuthenticationProcessingFilterEntryPoint
             logger.debug("Redirecting to: " + redirectUrl);
         }
 
-        ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response).encodeRedirectURL(
-                redirectUrl));
+        ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response)
+            .encodeRedirectURL(redirectUrl));
+    }
+
+    public boolean getForceHttps() {
+        return forceHttps;
+    }
+
+    public String getLoginFormUrl() {
+        return loginFormUrl;
+    }
+
+    public PortMapper getPortMapper() {
+        return portMapper;
+    }
+
+    public PortResolver getPortResolver() {
+        return portResolver;
+    }
+
+    /**
+     * 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
+     */
+    public void setForceHttps(boolean forceHttps) {
+        this.forceHttps = forceHttps;
+    }
+
+    /**
+     * 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;
+    }
+
+    public void setPortMapper(PortMapper portMapper) {
+        this.portMapper = portMapper;
+    }
+
+    public void setPortResolver(PortResolver portResolver) {
+        this.portResolver = portResolver;
     }
 }

+ 16 - 8
core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -12,11 +12,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.acegisecurity.ui.webapp;
 
 import junit.framework.TestCase;
 
 import org.acegisecurity.MockPortResolver;
+
 import org.acegisecurity.util.PortMapperImpl;
 
 import org.springframework.mock.web.MockHttpServletRequest;
@@ -34,14 +36,16 @@ import java.util.Map;
  * @version $Id$
  */
 public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
-    public final void setUp() throws Exception {
-        super.setUp();
-    }
+    //~ Methods ================================================================
 
     public static void main(String[] args) {
         junit.textui.TestRunner.run(AuthenticationProcessingFilterEntryPointTests.class);
     }
 
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
     public void testDetectsMissingLoginFormUrl() throws Exception {
         AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
         ep.setPortMapper(new PortMapperImpl());
@@ -172,13 +176,15 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
         ep.afterPropertiesSet();
 
         ep.commence(request, response, null);
-        assertEquals("/bigWebApp/hello", response.getRedirectedUrl());
+        assertEquals("https://www.example.com/bigWebApp/hello",
+            response.getRedirectedUrl());
 
         request.setServerPort(8443);
         response = new MockHttpServletResponse();
         ep.setPortResolver(new MockPortResolver(8080, 8443));
         ep.commence(request, response, null);
-        assertEquals("/bigWebApp/hello", response.getRedirectedUrl());
+        assertEquals("https://www.example.com:8443/bigWebApp/hello",
+            response.getRedirectedUrl());
     }
 
     public void testNormalOperation() throws Exception {
@@ -200,7 +206,8 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
 
         ep.afterPropertiesSet();
         ep.commence(request, response, null);
-        assertEquals("/bigWebApp/hello", response.getRedirectedUrl());
+        assertEquals("http://www.example.com/bigWebApp/hello",
+            response.getRedirectedUrl());
     }
 
     public void testOperationWhenHttpsRequestsButHttpsPortUnknown()
@@ -226,6 +233,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
         ep.commence(request, response, null);
 
         // Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to HTTP port mapping
-        assertEquals("/bigWebApp/hello", response.getRedirectedUrl());
+        assertEquals("http://www.example.com:8888/bigWebApp/hello",
+            response.getRedirectedUrl());
     }
 }