Explorar o código

SEC-413: Consistent redirect behaviour between LogoutFilter and AbstractProcessingFilter. (previous commit of AbstractProcessingFilter has an erroneous message).

Luke Taylor %!s(int64=18) %!d(string=hai) anos
pai
achega
477dc308f8

+ 7 - 4
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;
+    }
 }

+ 62 - 0
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));
+    }
+}