SEC-1226: Introduce RedirectStrategy to replace RedirectUtils. Implemented strategy and applied throughout relevant classes.
This commit is contained in:
parent
092d7b5c2b
commit
ab0d66071a
|
@ -167,15 +167,17 @@ public class OpenIDAuthenticationProcessingFilter extends AbstractAuthentication
|
|||
|
||||
if (mapping == null) {
|
||||
try {
|
||||
|
||||
URL url = new URL(returnToUrl);
|
||||
int port = (url.getPort() == -1) ? 80 : url.getPort();
|
||||
StringBuffer realmBuffer = new StringBuffer(returnToUrl.length())
|
||||
int port = url.getPort();
|
||||
|
||||
StringBuilder realmBuffer = new StringBuilder(returnToUrl.length())
|
||||
.append(url.getProtocol())
|
||||
.append("://")
|
||||
.append(url.getHost())
|
||||
.append(":").append(port)
|
||||
.append("/");
|
||||
.append(url.getHost());
|
||||
if (port > 0) {
|
||||
realmBuffer.append(":").append(port);
|
||||
}
|
||||
realmBuffer.append("/");
|
||||
mapping = realmBuffer.toString();
|
||||
} catch (MalformedURLException e) {
|
||||
logger.warn("returnToUrl was not a valid URL: [" + returnToUrl + "]", e);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package org.springframework.security.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Simple implementation of <tt>RedirectStrategy</tt> which is the default used throughout the framework.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DefaultRedirectStrategy implements RedirectStrategy {
|
||||
private boolean useRelativeContext;
|
||||
|
||||
/**
|
||||
* Redirects the response to the supplied URL.
|
||||
* <p>
|
||||
* If <tt>useRelativeContext</tt> is set, the redirect value will be the value after the request context path.
|
||||
*/
|
||||
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* If <tt>true</tt>, causes any redirection URLs to be calculated minus the protocol
|
||||
* and context path (defaults to <tt>false</tt>).
|
||||
*/
|
||||
public void setUseRelativeContext(boolean useRelativeContext) {
|
||||
this.useRelativeContext = useRelativeContext;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.springframework.security.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Encapsulates the redirection logic for all classes in the framework which perform redirects.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface RedirectStrategy {
|
||||
|
||||
/**
|
||||
* Performs a redirect to the supplied URL
|
||||
* @param request the current request
|
||||
* @param response the response to redirect
|
||||
* @param url the target URL to redirect to, for example "/login"
|
||||
*/
|
||||
void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException;
|
||||
}
|
|
@ -11,7 +11,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.util.RedirectUtils;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.RedirectStrategy;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
@ -50,8 +51,8 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
|||
private String targetUrlParameter = DEFAULT_TARGET_PARAMETER;
|
||||
private String defaultTargetUrl = "/";
|
||||
private boolean alwaysUseDefaultTargetUrl = false;
|
||||
private boolean useRelativeContext = false;
|
||||
private boolean useReferer = false;
|
||||
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||
|
||||
protected AbstractAuthenticationTargetUrlRequestHandler() {
|
||||
}
|
||||
|
@ -60,7 +61,7 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
|||
throws IOException, ServletException {
|
||||
String targetUrl = determineTargetUrl(request, response);
|
||||
|
||||
RedirectUtils.sendRedirect(request, response, targetUrl, useRelativeContext);
|
||||
redirectStrategy.sendRedirect(request, response, targetUrl);
|
||||
}
|
||||
|
||||
private String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
@ -149,15 +150,14 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
|
|||
}
|
||||
|
||||
/**
|
||||
* If <tt>true</tt>, causes any redirection URLs to be calculated minus the protocol
|
||||
* and context path (defaults to <tt>false</tt>).
|
||||
* Allows overriding of the behaviour when redirecting to a target URL.
|
||||
*/
|
||||
public void setUseRelativeContext(boolean useRelativeContext) {
|
||||
this.useRelativeContext = useRelativeContext;
|
||||
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
|
||||
this.redirectStrategy = redirectStrategy;
|
||||
}
|
||||
|
||||
protected boolean isUseRelativeContext() {
|
||||
return useRelativeContext;
|
||||
protected RedirectStrategy getRedirectStrategy() {
|
||||
return redirectStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.util.RedirectUtils;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
@ -35,7 +34,7 @@ public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthe
|
|||
String url = failureUrlMap.get(exception.getClass().getName());
|
||||
|
||||
if (url != null) {
|
||||
RedirectUtils.sendRedirect(request, response, url, isUseRelativeContext());
|
||||
getRedirectStrategy().sendRedirect(request, response, url);
|
||||
} else {
|
||||
super.onAuthenticationFailure(request, response, exception);
|
||||
}
|
||||
|
|
|
@ -17,24 +17,6 @@ package org.springframework.security.web.authentication;
|
|||
|
||||
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.PortMapper;
|
||||
import org.springframework.security.web.PortMapperImpl;
|
||||
import org.springframework.security.web.PortResolver;
|
||||
import org.springframework.security.web.PortResolverImpl;
|
||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||
import org.springframework.security.web.util.RedirectUrlBuilder;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
@ -42,6 +24,23 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.PortMapper;
|
||||
import org.springframework.security.web.PortMapperImpl;
|
||||
import org.springframework.security.web.PortResolver;
|
||||
import org.springframework.security.web.PortResolverImpl;
|
||||
import org.springframework.security.web.RedirectStrategy;
|
||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||
import org.springframework.security.web.util.RedirectUrlBuilder;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Used by the {@link ExceptionTranslationFilter} to commence a form login
|
||||
* authentication via the {@link UsernamePasswordAuthenticationProcessingFilter}. This object
|
||||
|
@ -80,6 +79,8 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
|||
|
||||
private boolean useForward = false;
|
||||
|
||||
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
@ -117,6 +118,8 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
|||
if (useForward) {
|
||||
|
||||
if (forceHttps && "http".equals(request.getScheme())) {
|
||||
// First redirect the current request to HTTPS.
|
||||
// When that request is received, the forward to the login page will be used.
|
||||
redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest);
|
||||
}
|
||||
|
||||
|
@ -140,7 +143,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
|||
|
||||
}
|
||||
|
||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
|
||||
redirectStrategy.sendRedirect(httpRequest, httpResponse, redirectUrl);
|
||||
}
|
||||
|
||||
protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
|
||||
|
@ -174,7 +177,8 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
|||
}
|
||||
|
||||
/**
|
||||
* Builds a URL to redirect the supplied request to HTTPS.
|
||||
* Builds a URL to redirect the supplied request to HTTPS. Used to redirect the current request
|
||||
* to HTTPS, before doing a forward to the login page.
|
||||
*/
|
||||
protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
|
||||
throws IOException, ServletException {
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.springframework.security.web.access.ExceptionTranslationFilter;
|
|||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
import org.springframework.security.web.util.RedirectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -76,7 +75,7 @@ public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuth
|
|||
// Use the SavedRequest URL
|
||||
String targetUrl = savedRequest.getFullRequestUrl();
|
||||
logger.debug("Redirecting to SavedRequest Url: " + targetUrl);
|
||||
RedirectUtils.sendRedirect(request, response, targetUrl, isUseRelativeContext());
|
||||
getRedirectStrategy().sendRedirect(request, response, targetUrl);
|
||||
}
|
||||
|
||||
public void setRequestCache(RequestCache requestCache) {
|
||||
|
|
|
@ -7,7 +7,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.util.RedirectUtils;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.RedirectStrategy;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
@ -27,7 +28,7 @@ import org.springframework.util.Assert;
|
|||
public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler {
|
||||
private String defaultFailureUrl;
|
||||
private boolean forwardToDestination = false;
|
||||
private boolean useRelativeContext = false;
|
||||
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||
|
||||
public SimpleUrlAuthenticationFailureHandler() {
|
||||
}
|
||||
|
@ -44,7 +45,7 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
|
|||
if (forwardToDestination) {
|
||||
request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
|
||||
} else {
|
||||
RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext);
|
||||
redirectStrategy.sendRedirect(request, response, defaultFailureUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,16 +72,14 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
|
|||
this.forwardToDestination = forwardToDestination;
|
||||
}
|
||||
|
||||
protected boolean isUseRelativeContext() {
|
||||
return useRelativeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, causes any redirection URLs to be calculated minus the protocol
|
||||
* and context path (defaults to false).
|
||||
* Allows overriding of the behaviour when redirecting to a target URL.
|
||||
*/
|
||||
public void setUseRelativeContext(boolean useRelativeContext) {
|
||||
this.useRelativeContext = useRelativeContext;
|
||||
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
|
||||
this.redirectStrategy = redirectStrategy;
|
||||
}
|
||||
|
||||
protected RedirectStrategy getRedirectStrategy() {
|
||||
return redirectStrategy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package org.springframework.security.web.util;
|
||||
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.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 AbstractAuthenticationProcessingFilter} 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 AbstractAuthenticationProcessingFilter#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));
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@ import org.springframework.security.core.userdetails.UserDetails;
|
|||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.authentication.switchuser.SwitchUserAuthorityChanger;
|
||||
import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
|
||||
|
@ -306,7 +307,9 @@ public class SwitchUserProcessingFilterTests {
|
|||
filter.setSwitchUserUrl("/j_spring_security_switch_user");
|
||||
SimpleUrlAuthenticationSuccessHandler switchSuccessHandler =
|
||||
new SimpleUrlAuthenticationSuccessHandler("/someOtherUrl");
|
||||
switchSuccessHandler.setUseRelativeContext(true);
|
||||
DefaultRedirectStrategy contextRelativeRedirector = new DefaultRedirectStrategy();
|
||||
contextRelativeRedirector.setUseRelativeContext(true);
|
||||
switchSuccessHandler.setRedirectStrategy(contextRelativeRedirector);
|
||||
filter.setSuccessHandler(switchSuccessHandler);
|
||||
filter.setUserDetailsService(new MockUserDetailsService());
|
||||
|
||||
|
|
Loading…
Reference in New Issue