SEC-174: Correct IE6 bug with AuthenticationProcessingFilterEntryPoint.

This commit is contained in:
Ben Alex 2006-02-08 04:58:50 +00:00
parent 9d213f46a4
commit 3a01e48b17
2 changed files with 83 additions and 64 deletions

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.acegisecurity.ui.webapp; package org.acegisecurity.ui.webapp;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.ui.AuthenticationEntryPoint; import org.acegisecurity.ui.AuthenticationEntryPoint;
import org.acegisecurity.util.PortMapper; import org.acegisecurity.util.PortMapper;
import org.acegisecurity.util.PortMapperImpl; import org.acegisecurity.util.PortMapperImpl;
import org.acegisecurity.util.PortResolver; 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, * holds the location of the login form, relative to the web app context path,
* and is used to commence a redirect to that form. * and is used to commence a redirect to that form.
* </p> * </p>
* *
* <p> * <p>
* By setting the <em>forceHttps</em> property to true, you may configure the * 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 * class to force the protocol used for the login form to be
@ -62,58 +65,18 @@ import javax.servlet.http.HttpServletResponse;
*/ */
public class AuthenticationProcessingFilterEntryPoint public class AuthenticationProcessingFilterEntryPoint
implements AuthenticationEntryPoint, InitializingBean { implements AuthenticationEntryPoint, InitializingBean {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class); private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class);
//~ Instance fields ========================================================
private PortMapper portMapper = new PortMapperImpl(); private PortMapper portMapper = new PortMapperImpl();
private PortResolver portResolver = new PortResolverImpl(); private PortResolver portResolver = new PortResolverImpl();
private String loginFormUrl; private String loginFormUrl;
private boolean forceHttps = false; private boolean forceHttps = false;
/** //~ 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
*/
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;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.hasLength(loginFormUrl, "loginFormUrl must be specified"); Assert.hasLength(loginFormUrl, "loginFormUrl must be specified");
@ -133,8 +96,7 @@ public class AuthenticationProcessingFilterEntryPoint
boolean inHttp = "http".equals(scheme.toLowerCase()); boolean inHttp = "http".equals(scheme.toLowerCase());
boolean inHttps = "https".equals(scheme.toLowerCase()); boolean inHttps = "https".equals(scheme.toLowerCase());
boolean includePort = ((inHttp && (serverPort == 80)) || boolean includePort = true;
(inHttps && (serverPort == 443)));
if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) { if ("http".equals(scheme.toLowerCase()) && (serverPort == 80)) {
includePort = false; includePort = false;
@ -144,7 +106,9 @@ public class AuthenticationProcessingFilterEntryPoint
includePort = false; includePort = false;
} }
String redirectUrl = contextPath + loginFormUrl; String redirectUrl = scheme + "://" + serverName
+ ((includePort) ? (":" + serverPort) : "") + contextPath
+ loginFormUrl;
if (forceHttps && inHttp) { if (forceHttps && inHttp) {
Integer httpPort = new Integer(portResolver.getServerPort(request)); Integer httpPort = new Integer(portResolver.getServerPort(request));
@ -157,9 +121,9 @@ public class AuthenticationProcessingFilterEntryPoint
includePort = true; includePort = true;
} }
redirectUrl = "https://" + serverName + redirectUrl = "https://" + serverName
((includePort) ? (":" + httpsPort) : "") + contextPath + + ((includePort) ? (":" + httpsPort) : "") + contextPath
loginFormUrl; + loginFormUrl;
} }
} }
@ -167,7 +131,54 @@ public class AuthenticationProcessingFilterEntryPoint
logger.debug("Redirecting to: " + redirectUrl); logger.debug("Redirecting to: " + redirectUrl);
} }
((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response).encodeRedirectURL( ((HttpServletResponse) response).sendRedirect(((HttpServletResponse) response)
redirectUrl)); .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;
} }
} }

View File

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