From e2de3c9dbcfaf42bb552a294dfb3f8238dffde53 Mon Sep 17 00:00:00 2001 From: Colin Sampaleanu Date: Thu, 22 Apr 2004 21:47:05 +0000 Subject: [PATCH] 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. --- .../AbstractSecurityInterceptor.java | 11 +- .../intercept/web/FilterInvocation.java | 8 + .../web/SecurityEnforcementFilter.java | 4 +- .../cas/CasAuthenticationProvider.java | 3 +- .../providers/cas/CasAuthenticationToken.java | 4 +- .../ui/AbstractProcessingFilter.java | 9 +- .../ui/cas/CasProcessingFilter.java | 2 +- .../ui/cas/ServiceProperties.java | 31 +-- ...henticationProcessingFilterEntryPoint.java | 178 ++++++++++++------ .../org/acegisecurity/userdetails/User.java | 4 +- .../acegisecurity/MockHttpServletRequest.java | 29 ++- .../intercept/web/FilterInvocationTests.java | 10 + .../web/SecurityEnforcementFilterTests.java | 4 +- .../ui/cas/ServicePropertiesTests.java | 2 +- ...cationProcessingFilterEntryPointTests.java | 109 +++++++---- test/acegisecuritytest.properties | 2 +- 16 files changed, 284 insertions(+), 126 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java index 717625e5a6..8fb9e40742 100644 --- a/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java +++ b/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); } diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java index 08cff383b3..8da6bb1ab0 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterInvocation.java @@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletResponse; *

* * @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; } diff --git a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java b/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java index 97ca68f051..0ed9cef42a 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java +++ b/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()) { diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java index 9e78ef5303..1b8b2cc1a3 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java +++ b/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"); } diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java index d0e90fa2ce..40aae63154 100644 --- a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationToken.java +++ b/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; diff --git a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java index df3bf763eb..3cc52f279b 100644 --- a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java @@ -63,7 +63,9 @@ import javax.servlet.http.HttpServletResponse; * defaultTargetUrl indicates the URL that should be used for * redirection if the HttpSession attribute named {@link * #ACEGI_SECURITY_TARGET_URL_KEY} does not indicate the target URL once - * authentication is completed successfully. eg: /. + * authentication is completed successfully. eg: /. This will be + * treated as relative to the web-app's context path, and should include the + * leading /. * *
  • * authenticationFailureUrl 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; } diff --git a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java index c4dea63ece..07ebb07287 100644 --- a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilter.java +++ b/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 = ""; } diff --git a/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java b/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java index d87258a8af..6c8a1624bf 100644 --- a/core/src/main/java/org/acegisecurity/ui/cas/ServiceProperties.java +++ b/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 renew parameter should be sent to the * CAS login URL and CAS validation URL. - *

    If true, 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 true. - * Defaults to false, providing automated single sign on. + * + *

    + * If true, 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 true. Defaults to false, providing + * automated single sign on. + *

    * * @return whether to send the renew parameter to CAS */ @@ -65,13 +67,14 @@ public class ServiceProperties implements InitializingBean { } /** - * Represents the service the user is authenticating to. - * - * 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. + * + *

    + * This service is the callback URL belonging to the local Acegi Security + * System for Spring secured application. For example, + *

    * https://www.mycompany.com/application/j_acegi_cas_security_check - * + * * @return the URL of the service the user is authenticating to */ public String getService() { diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java index 7840f85686..21133b8b76 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java +++ b/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; /** + *

    * Used by the SecurityEnforcementFilter 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. + *

    + * + *

    + * By setting the forceHttps property to true, you may configure the + * class to force the protocol used for the login form to be + * https, even if the original intercepted request for a resource + * used the http 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 httpsPortMappings 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 forceHttps property. + *

    * * @author Ben Alex * @author colin sampaleanu @@ -43,24 +67,95 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean { //~ Instance fields ======================================================== - /** - * The URL where the AuthenticationProcessingFilter 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 + * https, then + * + * @param forceHttps + * + * @todo Generated comment + */ + public void setForceHttps(boolean forceHttps) { + this.forceHttps = forceHttps; + } + + public boolean getForceHttps() { + return forceHttps; } + /** + *

    + * Set to override the default http port to https port mappings of 80:443, + * and 8080:8443. + *

    + * In a Spring XML ApplicationContext, a definition would look something + * like this: + *
    +     *   <property name="httpsPortMapping">
    +     *     <map>
    +     *       <entry key="80"><value>443</value></entry>
    +     *       <entry key="8080"><value>8443</value></entry>
    +     *     </map>
    +     *   </property>
    +     * 
    + * + * @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 AuthenticationProcessingFilter login page + * can be found. Should be relative to the web-app context path, and + * include a leading / + * + * @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; } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/User.java b/core/src/main/java/org/acegisecurity/userdetails/User.java index e5c5813c26..2c46e51b52 100644 --- a/core/src/main/java/org/acegisecurity/userdetails/User.java +++ b/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}. diff --git a/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java b/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java index 2a89e02b95..c06baea30d 100644 --- a/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java +++ b/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java @@ -42,6 +42,7 @@ import javax.servlet.http.HttpSession; *

    * * @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) { diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java index 591945e68e..44d86ac720 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/FilterInvocationTests.java +++ b/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 ========================================================== diff --git a/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java b/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java index 51eed372f4..20c5e4010b 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java +++ b/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)); } diff --git a/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java b/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java index e1ffb755bf..f0605311f1 100644 --- a/core/src/test/java/org/acegisecurity/ui/cas/ServicePropertiesTests.java +++ b/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(); } } diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java index a82c27e20a..ba1f33dd4c 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java +++ b/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))); } - } diff --git a/test/acegisecuritytest.properties b/test/acegisecuritytest.properties index 4a24668df3..67413b189e 100644 --- a/test/acegisecuritytest.properties +++ b/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