diff --git a/core/src/main/java/org/springframework/security/ui/TargetUrlResolver.java b/core/src/main/java/org/springframework/security/ui/TargetUrlResolver.java index 1b12547df6..7cd95d0461 100644 --- a/core/src/main/java/org/springframework/security/ui/TargetUrlResolver.java +++ b/core/src/main/java/org/springframework/security/ui/TargetUrlResolver.java @@ -22,7 +22,7 @@ import org.springframework.security.ui.savedrequest.SavedRequest; /** * Used by {@link AbstractProcessingFilter} to determine target URL in case of - * successfull authentication. + * successful authentication. * * @author Martino Piccinato * @version $Id$ @@ -34,7 +34,7 @@ public interface TargetUrlResolver { /** * @param savedRequest The request that initiated the authentication process * @param currentRequest the current request - * @param auth The authentication token generated after successfull authentication + * @param auth The authentication token generated after successful authentication * @return The URL to be used */ public String determineTargetUrl(SavedRequest savedRequest, HttpServletRequest currentRequest, Authentication auth); diff --git a/core/src/main/java/org/springframework/security/ui/TargetUrlResolverImpl.java b/core/src/main/java/org/springframework/security/ui/TargetUrlResolverImpl.java index 176ee647cd..ef10dd1ecb 100644 --- a/core/src/main/java/org/springframework/security/ui/TargetUrlResolverImpl.java +++ b/core/src/main/java/org/springframework/security/ui/TargetUrlResolverImpl.java @@ -15,26 +15,38 @@ package org.springframework.security.ui; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + import javax.servlet.http.HttpServletRequest; import org.springframework.security.Authentication; import org.springframework.security.ui.savedrequest.SavedRequest; +import org.springframework.util.StringUtils; /** * Default implementation for {@link TargetUrlResolver} + *
+ * Returns a target URL based from the contents of the configured targetUrlParameter if present on
+ * the current request. Failing that, the SavedRequest in the session will be used.
*
* @author Martino Piccinato
+ * @author Luke Taylor
* @version $Id$
* @since 2.0
*
*/
public class TargetUrlResolverImpl implements TargetUrlResolver {
+ public static String DEFAULT_TARGET_PARAMETER = "redirect";
+
+ /* SEC-213 */
+ private String targetUrlParameter;
/**
- * If true, will only use SavedRequest to determine the target url on successful
+ * If true, will only use SavedRequest to determine the target URL on successful
* authentication if the request that caused the authentication request was a GET.
- * It will return null on POST/PUT request.
- * In most cases it's meaningless to redirect to a Url generated by a POST/PUT request.
+ * It will return null for a POST/PUT request.
+ * In most cases it's meaningless to redirect to a URL generated by a POST/PUT request.
* Defaults to true.
*/
private boolean justUseSavedRequestOnGet = true;
@@ -46,6 +58,18 @@ public class TargetUrlResolverImpl implements TargetUrlResolver {
Authentication auth) {
String targetUrl = null;
+
+ if (targetUrlParameter != null) {
+ targetUrl = currentRequest.getParameter(targetUrlParameter);
+
+ if (StringUtils.hasText(targetUrl)) {
+ try {
+ return URLDecoder.decode(targetUrl, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException("UTF-8 not supported. Shouldn't be possible");
+ }
+ }
+ }
if (savedRequest != null) {
if (!justUseSavedRequestOnGet || savedRequest.getMethod().equals("GET")) {
@@ -72,5 +96,19 @@ public class TargetUrlResolverImpl implements TargetUrlResolver {
public void setJustUseSavedRequestOnGet(boolean justUseSavedRequestOnGet) {
this.justUseSavedRequestOnGet = justUseSavedRequestOnGet;
}
+
+
+ /**
+ * Before checking the SavedRequest, the current request will be checked for this parameter
+ * and the value used as the target URL if resent.
+ *
+ * @param targetUrlParameter the name of the parameter containing the encoded target URL. Defaults
+ * to "redirect".
+ */
+ public void setTargetUrlParameter(String targetUrlParameter) {
+ this.targetUrlParameter = targetUrlParameter;
+ }
+
+
}
diff --git a/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java b/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java
index e3b857265d..ecc3cc74bb 100644
--- a/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java
+++ b/core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java
@@ -571,6 +571,29 @@ public class AbstractProcessingFilterTests extends TestCase {
assertEquals("/error", response.getForwardedUrl());
}
+ /**
+ * SEC-213
+ */
+ public void testTargetUrlParameterIsUsedIfPresent() throws Exception {
+ MockHttpServletRequest request = createMockRequest();
+ request.setParameter("targetUrl", "/target");
+
+ MockFilterConfig config = new MockFilterConfig(null, null);
+ MockFilterChain chain = new MockFilterChain(true);
+ MockHttpServletResponse response = new MockHttpServletResponse();
+
+ MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
+ TargetUrlResolverImpl targetUrlResolver = new TargetUrlResolverImpl();
+ targetUrlResolver.setTargetUrlParameter("targetUrl");
+ filter.setTargetUrlResolver(targetUrlResolver);
+ filter.setDefaultTargetUrl("http://monkeymachine.co.uk/");
+ filter.setAuthenticationFailureUrl("/error");
+
+ executeFilterInContainerSimulator(config, filter, request, response, chain);
+
+ assertEquals("/mycontext/target", response.getRedirectedUrl());
+ }
+
//~ Inner Classes ==================================================================================================