From 477dc308f8e988026181bb5c3c41940de72830be Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Wed, 19 Sep 2007 16:27:23 +0000 Subject: [PATCH] SEC-413: Consistent redirect behaviour between LogoutFilter and AbstractProcessingFilter. (previous commit of AbstractProcessingFilter has an erroneous message). --- .../acegisecurity/ui/logout/LogoutFilter.java | 11 ++-- .../org/acegisecurity/util/RedirectUtils.java | 62 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/org/acegisecurity/util/RedirectUtils.java diff --git a/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java b/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java index c9f1971b0e..d5a043e69c 100644 --- a/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/logout/LogoutFilter.java @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.acegisecurity.Authentication; +import org.acegisecurity.util.RedirectUtils; import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -60,6 +61,7 @@ public class LogoutFilter implements Filter { private String filterProcessesUrl = "/j_acegi_logout"; private String logoutSuccessUrl; private LogoutHandler[] handlers; + private boolean useRelativeContext; //~ Constructors =================================================================================================== @@ -162,11 +164,8 @@ public class LogoutFilter implements Filter { */ protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException { - if (!url.startsWith("http://") && !url.startsWith("https://")) { - url = request.getContextPath() + url; - } - response.sendRedirect(response.encodeRedirectURL(url)); + RedirectUtils.sendRedirect(request, response, url, useRelativeContext); } public void setFilterProcessesUrl(String filterProcessesUrl) { @@ -177,4 +176,8 @@ public class LogoutFilter implements Filter { protected String getFilterProcessesUrl() { return filterProcessesUrl; } + + public void setUseRelativeContext(boolean useRelativeContext) { + this.useRelativeContext = useRelativeContext; + } } diff --git a/core/src/main/java/org/acegisecurity/util/RedirectUtils.java b/core/src/main/java/org/acegisecurity/util/RedirectUtils.java new file mode 100644 index 0000000000..ccebba9cb9 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/util/RedirectUtils.java @@ -0,0 +1,62 @@ +package org.acegisecurity.util; + +import org.acegisecurity.ui.AbstractProcessingFilter; +import org.acegisecurity.ui.logout.LogoutFilter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Luke Taylor + * @version $Id$ + */ +public abstract class RedirectUtils { + //~ Constructors =================================================================================================== + + private RedirectUtils() { + } + + //~ Methods ======================================================================================================== + + /** + * Encapsulates the redirect logic used in classes like {@link AbstractProcessingFilter} and {@link LogoutFilter}. + * + * @param request the incoming request + * @param response the response to redirect + * @param url the target url to redirect to + * @param useRelativeContext if true, causes any redirection URLs to be calculated minus the protocol + * and context path. + * + * @see AbstractProcessingFilter#setUseRelativeContext(boolean) + */ + public static final void sendRedirect(HttpServletRequest request, + HttpServletResponse response, + String url, + boolean useRelativeContext) throws IOException { + String finalUrl; + if (!url.startsWith("http://") && !url.startsWith("https://")) { + if (useRelativeContext) { + finalUrl = url; + } + else { + finalUrl = request.getContextPath() + url; + } + } + else if (useRelativeContext) { + // Calculate the relative URL from the fully qualifed URL, minus the protocol and base context. + int len = request.getContextPath().length(); + int index = url.indexOf(request.getContextPath()) + len; + finalUrl = url.substring(index); + + if (finalUrl.length() > 1 && finalUrl.charAt(0) == '/') { + finalUrl = finalUrl.substring(1); + } + } + else { + finalUrl = url; + } + + response.sendRedirect(response.encodeRedirectURL(finalUrl)); + } +}