SEC-1167: Introduce more flexible SavedRequest handling. Introduced interface for SavedRequest.

This commit is contained in:
Luke Taylor 2009-09-13 15:03:14 +00:00
parent 71ab83255d
commit 4064b7b4f6
15 changed files with 442 additions and 394 deletions

View File

@ -67,7 +67,7 @@ import org.springframework.web.filter.GenericFilterBean;
* The configured {@link #setAuthenticationSuccessHandler(AuthenticationSuccessHandler) AuthenticationSuccessHandler} will
* then be called to take the redirect to the appropriate destination after a successful login. The default behaviour
* is implemented in a {@link SavedRequestAwareAuthenticationSuccessHandler} which will make use of any
* <tt>SavedRequest</tt> set by the <tt>ExceptionTranslationFilter</tt> and redirect the user to the URL contained
* <tt>DefaultSavedRequest</tt> set by the <tt>ExceptionTranslationFilter</tt> and redirect the user to the URL contained
* therein. Otherwise it will redirect to the webapp root "/". You can customize this behaviour by injecting a
* differently configured instance of this class, or by using a different implementation.
* <p>

View File

@ -13,10 +13,11 @@ 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.savedrequest.DefaultSavedRequest;
import org.springframework.util.StringUtils;
/**
* An authentication success strategy which can make use of the {@link SavedRequest} which may have been stored in
* An authentication success strategy which can make use of the {@link DefaultSavedRequest} which may have been stored in
* the session by the {@link ExceptionTranslationFilter}. When such a request is intercepted and requires authentication,
* the request data is stored to record the original destination before the authentication process commenced, and to
* allow the request to be reconstructed when a redirect to the same URL occurs. This class is responsible for
@ -26,21 +27,21 @@ import org.springframework.util.StringUtils;
* <ul>
* <li>
* If the <tt>alwaysUseDefaultTargetUrl</tt> property is set to true, the <tt>defaultTargetUrl</tt>
* will be used for the destination. Any <tt>SavedRequest</tt> stored in the session will be
* will be used for the destination. Any <tt>DefaultSavedRequest</tt> stored in the session will be
* removed.
* </li>
* <li>
* If the <tt>targetUrlParameter</tt> has been set on the request, the value will be used as the destination.
* Any <tt>SavedRequest</tt> will again be removed.
* Any <tt>DefaultSavedRequest</tt> will again be removed.
* </li>
* <li>
* If a {@link SavedRequest} is found in the <tt>RequestCache</tt> (as set by the {@link ExceptionTranslationFilter} to
* If a {@link DefaultSavedRequest} is found in the <tt>RequestCache</tt> (as set by the {@link ExceptionTranslationFilter} to
* record the original destination before the authentication process commenced), a redirect will be performed to the
* Url of that original destination. The <tt>SavedRequest</tt> object will remain cached and be picked up
* Url of that original destination. The <tt>DefaultSavedRequest</tt> object will remain cached and be picked up
* when the redirected request is received (See {@link SavedRequestAwareWrapper}).
* </li>
* <li>
* If no <tt>SavedRequest</tt> is found, it will delegate to the base class.
* If no <tt>DefaultSavedRequest</tt> is found, it will delegate to the base class.
* </li>
* </ul>
*
@ -72,9 +73,9 @@ public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuth
return;
}
// Use the SavedRequest URL
String targetUrl = savedRequest.getFullRequestUrl();
logger.debug("Redirecting to SavedRequest Url: " + targetUrl);
// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}

View File

@ -0,0 +1,341 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.savedrequest;
import org.springframework.security.web.PortResolver;
import org.springframework.security.web.util.UrlUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
/**
* Represents central information from a <code>HttpServletRequest</code>.<p>This class is used by {@link
* org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and {@link org.springframework.security.web.savedrequest.SavedRequestAwareWrapper} to
* reproduce the request after successful authentication. An instance of this class is stored at the time of an
* authentication exception by {@link org.springframework.security.web.access.ExceptionTranslationFilter}.</p>
* <p><em>IMPLEMENTATION NOTE</em>: It is assumed that this object is accessed only from the context of a single
* thread, so no synchronization around internal collection classes is performed.</p>
* <p>This class is based on code in Apache Tomcat.</p>
*
* @author Craig McClanahan
* @author Andrey Grebnev
* @author Ben Alex
* @version $Id$
*/
public class DefaultSavedRequest implements SavedRequest {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(DefaultSavedRequest.class);
public static final String SPRING_SECURITY_SAVED_REQUEST_KEY = "SPRING_SECURITY_SAVED_REQUEST_KEY";
//~ Instance fields ================================================================================================
private ArrayList<SavedCookie> cookies = new ArrayList<SavedCookie>();
private ArrayList<Locale> locales = new ArrayList<Locale>();
private Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
private Map<String, String[]> parameters = new TreeMap<String, String[]>(String.CASE_INSENSITIVE_ORDER);
private String contextPath;
private String method;
private String pathInfo;
private String queryString;
private String requestURI;
private String requestURL;
private String scheme;
private String serverName;
private String servletPath;
private int serverPort;
//~ Constructors ===================================================================================================
@SuppressWarnings("unchecked")
public DefaultSavedRequest(HttpServletRequest request, PortResolver portResolver) {
Assert.notNull(request, "Request required");
Assert.notNull(portResolver, "PortResolver required");
// Cookies
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
this.addCookie(cookies[i]);
}
}
// Headers
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
Enumeration<String> values = request.getHeaders(name);
while (values.hasMoreElements()) {
this.addHeader(name, values.nextElement());
}
}
// Locales
Enumeration<Locale> locales = request.getLocales();
while (locales.hasMoreElements()) {
Locale locale = (Locale) locales.nextElement();
this.addLocale(locale);
}
// Parameters
Map<String,Object> parameters = request.getParameterMap();
for(String paramName : parameters.keySet()) {
Object paramValues = parameters.get(paramName);
if (paramValues instanceof String[]) {
this.addParameter(paramName, (String[]) paramValues);
} else {
if (logger.isWarnEnabled()) {
logger.warn("ServletRequest.getParameterMap() returned non-String array");
}
}
}
// Primitives
this.method = request.getMethod();
this.pathInfo = request.getPathInfo();
this.queryString = request.getQueryString();
this.requestURI = request.getRequestURI();
this.serverPort = portResolver.getServerPort(request);
this.requestURL = request.getRequestURL().toString();
this.scheme = request.getScheme();
this.serverName = request.getServerName();
this.contextPath = request.getContextPath();
this.servletPath = request.getServletPath();
}
//~ Methods ========================================================================================================
private void addCookie(Cookie cookie) {
cookies.add(new SavedCookie(cookie));
}
private void addHeader(String name, String value) {
List<String> values = headers.get(name);
if (values == null) {
values = new ArrayList<String>();
headers.put(name, values);
}
values.add(value);
}
private void addLocale(Locale locale) {
locales.add(locale);
}
private void addParameter(String name, String[] values) {
parameters.put(name, values);
}
/**
* Determines if the current request matches the <code>DefaultSavedRequest</code>.
* <p>
* All URL arguments are considered but not cookies, locales, headers or parameters.
* <p>
*
*/
public boolean doesRequestMatch(HttpServletRequest request, PortResolver portResolver) {
if (!propertyEquals("pathInfo", this.pathInfo, request.getPathInfo())) {
return false;
}
if (!propertyEquals("queryString", this.queryString, request.getQueryString())) {
return false;
}
if (!propertyEquals("requestURI", this.requestURI, request.getRequestURI())) {
return false;
}
if (!"GET".equals(request.getMethod()) && "GET".equals(method)) {
// A save GET should not match an incoming non-GET method
return false;
}
if (!propertyEquals("serverPort", new Integer(this.serverPort), new Integer(portResolver.getServerPort(request))))
{
return false;
}
if (!propertyEquals("requestURL", this.requestURL, request.getRequestURL().toString())) {
return false;
}
if (!propertyEquals("scheme", this.scheme, request.getScheme())) {
return false;
}
if (!propertyEquals("serverName", this.serverName, request.getServerName())) {
return false;
}
if (!propertyEquals("contextPath", this.contextPath, request.getContextPath())) {
return false;
}
if (!propertyEquals("servletPath", this.servletPath, request.getServletPath())) {
return false;
}
return true;
}
public String getContextPath() {
return contextPath;
}
public List<Cookie> getCookies() {
List<Cookie> cookieList = new ArrayList<Cookie>(cookies.size());
for (SavedCookie savedCookie : cookies) {
cookieList.add(savedCookie.getCookie());
}
return cookieList;
}
/**
* Indicates the URL that the user agent used for this request.
*
* @return the full URL of this request
*/
public String getRedirectUrl() {
return UrlUtils.buildFullRequestUrl(scheme, serverName, serverPort, contextPath, servletPath, requestURI,
pathInfo, queryString);
}
public Iterator<String> getHeaderNames() {
return (headers.keySet().iterator());
}
public Iterator<String> getHeaderValues(String name) {
List<String> values = headers.get(name);
if (values == null) {
values = Collections.emptyList();
}
return (values.iterator());
}
public Iterator<Locale> getLocales() {
return (locales.iterator());
}
public String getMethod() {
return method;
}
public Map<String, String[]> getParameterMap() {
return parameters;
}
public Iterator<String> getParameterNames() {
return (parameters.keySet().iterator());
}
public String[] getParameterValues(String name) {
return ((String[]) parameters.get(name));
}
public String getPathInfo() {
return pathInfo;
}
public String getQueryString() {
return (this.queryString);
}
public String getRequestURI() {
return (this.requestURI);
}
public String getRequestURL() {
return requestURL;
}
public String getScheme() {
return scheme;
}
public String getServerName() {
return serverName;
}
public int getServerPort() {
return serverPort;
}
public String getServletPath() {
return servletPath;
}
private boolean propertyEquals(String log, Object arg1, Object arg2) {
if ((arg1 == null) && (arg2 == null)) {
if (logger.isDebugEnabled()) {
logger.debug(log + ": both null (property equals)");
}
return true;
}
if (((arg1 == null) && (arg2 != null)) || ((arg1 != null) && (arg2 == null))) {
if (logger.isDebugEnabled()) {
logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property not equals)");
}
return false;
}
if (arg1.equals(arg2)) {
if (logger.isDebugEnabled()) {
logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property equals)");
}
return true;
} else {
if (logger.isDebugEnabled()) {
logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property not equals)");
}
return false;
}
}
public String toString() {
return "DefaultSavedRequest[" + getRedirectUrl() + "]";
}
}

View File

@ -10,7 +10,9 @@ import org.springframework.security.web.PortResolver;
import org.springframework.security.web.PortResolverImpl;
/**
* <tt>RequestCache</tt> which stores the SavedRequest in the HttpSession.
* <tt>RequestCache</tt> which stores the <tt>SavedRequest</tt> in the HttpSession.
*
* The {@link DefaultSavedRequest} class is used as the implementation.
*
* @author Luke Taylor
* @version $Id$
@ -28,13 +30,13 @@ public class HttpSessionRequestCache implements RequestCache {
*/
public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
if (!justUseSavedRequestOnGet || "GET".equals(request.getMethod())) {
SavedRequest savedRequest = new SavedRequest(request, portResolver);
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, portResolver);
if (createSessionAllowed || request.getSession(false) != null) {
// Store the HTTP request itself. Used by AbstractAuthenticationProcessingFilter
// for redirection after successful authentication (SEC-29)
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
logger.debug("SavedRequest added to Session: " + savedRequest);
request.getSession().setAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
logger.debug("DefaultSavedRequest added to Session: " + savedRequest);
}
}
@ -44,7 +46,7 @@ public class HttpSessionRequestCache implements RequestCache {
HttpSession session = currentRequest.getSession(false);
if (session != null) {
return (SavedRequest) session.getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
return (DefaultSavedRequest) session.getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
}
return null;
@ -54,13 +56,13 @@ public class HttpSessionRequestCache implements RequestCache {
HttpSession session = currentRequest.getSession(false);
if (session != null) {
logger.debug("Removing SavedRequest from session if present");
session.removeAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
logger.debug("Removing DefaultSavedRequest from session if present");
session.removeAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
}
}
public HttpServletRequest getMatchingRequest(HttpServletRequest request, HttpServletResponse response) {
SavedRequest saved = getRequest(request, response);
DefaultSavedRequest saved = (DefaultSavedRequest) getRequest(request, response);
if (saved == null) {
return null;
@ -77,7 +79,7 @@ public class HttpSessionRequestCache implements RequestCache {
}
/**
* If <code>true</code>, will only use <code>SavedRequest</code> to determine the target URL on successful
* If <code>true</code>, will only use <code>DefaultSavedRequest</code> to determine the target URL on successful
* authentication if the request that caused the authentication request was a GET. Defaults to false.
*/
public void setJustUseSavedRequestOnGet(boolean justUseSavedRequestOnGet) {

View File

@ -34,7 +34,8 @@ public interface RequestCache {
*
* @param request
* @param response
* @return the wrapped save request, if it matches the
* @return the wrapped save request, if it matches the original, or null if there is no cached request or it doesn't
* match.
*/
HttpServletRequest getMatchingRequest(HttpServletRequest request, HttpServletResponse response);

View File

@ -1,345 +1,17 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.savedrequest;
import org.springframework.security.web.PortResolver;
import org.springframework.security.web.util.UrlUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
/**
* Represents central information from a <code>HttpServletRequest</code>.<p>This class is used by {@link
* org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and {@link org.springframework.security.web.savedrequest.SavedRequestAwareWrapper} to
* reproduce the request after successful authentication. An instance of this class is stored at the time of an
* authentication exception by {@link org.springframework.security.web.access.ExceptionTranslationFilter}.</p>
* <p><em>IMPLEMENTATION NOTE</em>: It is assumed that this object is accessed only from the context of a single
* thread, so no synchronization around internal collection classes is performed.</p>
* <p>This class is based on code in Apache Tomcat.</p>
*
* @author Craig McClanahan
* @author Andrey Grebnev
* @author Ben Alex
* @version $Id$
*/
public class SavedRequest implements java.io.Serializable {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(SavedRequest.class);
public static final String SPRING_SECURITY_SAVED_REQUEST_KEY = "SPRING_SECURITY_SAVED_REQUEST_KEY";
//~ Instance fields ================================================================================================
private ArrayList<SavedCookie> cookies = new ArrayList<SavedCookie>();
private ArrayList<Locale> locales = new ArrayList<Locale>();
private Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
private Map<String, String[]> parameters = new TreeMap<String, String[]>(String.CASE_INSENSITIVE_ORDER);
private String contextPath;
private String method;
private String pathInfo;
private String queryString;
private String requestURI;
private String requestURL;
private String scheme;
private String serverName;
private String servletPath;
private int serverPort;
//~ Constructors ===================================================================================================
@SuppressWarnings("unchecked")
public SavedRequest(HttpServletRequest request, PortResolver portResolver) {
Assert.notNull(request, "Request required");
Assert.notNull(portResolver, "PortResolver required");
// Cookies
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
this.addCookie(cookies[i]);
}
}
// Headers
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
Enumeration<String> values = request.getHeaders(name);
while (values.hasMoreElements()) {
this.addHeader(name, values.nextElement());
}
}
// Locales
Enumeration<Locale> locales = request.getLocales();
while (locales.hasMoreElements()) {
Locale locale = (Locale) locales.nextElement();
this.addLocale(locale);
}
// Parameters
Map<String,Object> parameters = request.getParameterMap();
for(String paramName : parameters.keySet()) {
Object paramValues = parameters.get(paramName);
if (paramValues instanceof String[]) {
this.addParameter(paramName, (String[]) paramValues);
} else {
if (logger.isWarnEnabled()) {
logger.warn("ServletRequest.getParameterMap() returned non-String array");
}
}
}
// Primitives
this.method = request.getMethod();
this.pathInfo = request.getPathInfo();
this.queryString = request.getQueryString();
this.requestURI = request.getRequestURI();
this.serverPort = portResolver.getServerPort(request);
this.requestURL = request.getRequestURL().toString();
this.scheme = request.getScheme();
this.serverName = request.getServerName();
this.contextPath = request.getContextPath();
this.servletPath = request.getServletPath();
}
//~ Methods ========================================================================================================
private void addCookie(Cookie cookie) {
cookies.add(new SavedCookie(cookie));
}
private void addHeader(String name, String value) {
List<String> values = headers.get(name);
if (values == null) {
values = new ArrayList<String>();
headers.put(name, values);
}
values.add(value);
}
private void addLocale(Locale locale) {
locales.add(locale);
}
private void addParameter(String name, String[] values) {
parameters.put(name, values);
}
/**
* Determines if the current request matches the <code>SavedRequest</code>. All URL arguments are
* considered, but <em>not</em> method (POST/GET), cookies, locales, headers or parameters.
*/
public boolean doesRequestMatch(HttpServletRequest request, PortResolver portResolver) {
Assert.notNull(request, "Request required");
Assert.notNull(portResolver, "PortResolver required");
if (!propertyEquals("pathInfo", this.pathInfo, request.getPathInfo())) {
return false;
}
if (!propertyEquals("queryString", this.queryString, request.getQueryString())) {
return false;
}
if (!propertyEquals("requestURI", this.requestURI, request.getRequestURI())) {
return false;
}
if (!propertyEquals("serverPort", new Integer(this.serverPort), new Integer(portResolver.getServerPort(request))))
{
return false;
}
if (!propertyEquals("requestURL", this.requestURL, request.getRequestURL().toString())) {
return false;
}
if (!propertyEquals("scheme", this.scheme, request.getScheme())) {
return false;
}
if (!propertyEquals("serverName", this.serverName, request.getServerName())) {
return false;
}
if (!propertyEquals("contextPath", this.contextPath, request.getContextPath())) {
return false;
}
if (!propertyEquals("servletPath", this.servletPath, request.getServletPath())) {
return false;
}
return true;
}
public String getContextPath() {
return contextPath;
}
public List<Cookie> getCookies() {
List<Cookie> cookieList = new ArrayList<Cookie>(cookies.size());
for (SavedCookie savedCookie : cookies) {
cookieList.add(savedCookie.getCookie());
}
return cookieList;
}
/**
* Indicates the URL that the user agent used for this request.
*
* @return the full URL of this request
*/
public String getFullRequestUrl() {
return UrlUtils.buildFullRequestUrl(this.getScheme(), this.getServerName(), this.getServerPort(), this.getContextPath(),
this.getServletPath(), this.getRequestURI(), this.getPathInfo(), this.getQueryString());
}
public Iterator<String> getHeaderNames() {
return (headers.keySet().iterator());
}
public Iterator<String> getHeaderValues(String name) {
List<String> values = headers.get(name);
if (values == null) {
values = Collections.emptyList();
}
return (values.iterator());
}
public Iterator<Locale> getLocales() {
return (locales.iterator());
}
public String getMethod() {
return method;
}
public Map<String, String[]> getParameterMap() {
return parameters;
}
public Iterator<String> getParameterNames() {
return (parameters.keySet().iterator());
}
public String[] getParameterValues(String name) {
return ((String[]) parameters.get(name));
}
public String getPathInfo() {
return pathInfo;
}
public String getQueryString() {
return (this.queryString);
}
public String getRequestURI() {
return (this.requestURI);
}
public String getRequestURL() {
return requestURL;
}
/**
* Obtains the web application-specific fragment of the URL.
*
* @return the URL, excluding any server name, context path or servlet path
*/
public String getRequestUrl() {
return UrlUtils.buildRequestUrl(this.getServletPath(), this.getRequestURI(), this.getContextPath(), this.getPathInfo(),
this.getQueryString());
}
public String getScheme() {
return scheme;
}
public String getServerName() {
return serverName;
}
public int getServerPort() {
return serverPort;
}
public String getServletPath() {
return servletPath;
}
private boolean propertyEquals(String log, Object arg1, Object arg2) {
if ((arg1 == null) && (arg2 == null)) {
if (logger.isDebugEnabled()) {
logger.debug(log + ": both null (property equals)");
}
return true;
}
if (((arg1 == null) && (arg2 != null)) || ((arg1 != null) && (arg2 == null))) {
if (logger.isDebugEnabled()) {
logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property not equals)");
}
return false;
}
if (arg1.equals(arg2)) {
if (logger.isDebugEnabled()) {
logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property equals)");
}
return true;
} else {
if (logger.isDebugEnabled()) {
logger.debug(log + ": arg1=" + arg1 + "; arg2=" + arg2 + " (property not equals)");
}
return false;
}
}
public String toString() {
return "SavedRequest[" + getFullRequestUrl() + "]";
}
}
package org.springframework.security.web.savedrequest;
/**
* Encapsulates the functionality required of a cached request, in order for an authentication mechanism (typically
* form-based login) to redirect to the original URL.
*
* @author Luke Taylor
* @version $Id$
* @since 3.0
*/
public interface SavedRequest extends java.io.Serializable {
/**
* @return the URL for the saved request, allowing a redirect to be performed.
*/
String getRedirectUrl();
}

View File

@ -65,7 +65,7 @@ class SavedRequestAwareWrapper extends HttpServletRequestWrapper {
//~ Instance fields ================================================================================================
protected SavedRequest savedRequest = null;
protected DefaultSavedRequest savedRequest = null;
/**
* The set of SimpleDateFormat formats to use in getDateHeader(). Notice that because SimpleDateFormat is
@ -75,7 +75,7 @@ class SavedRequestAwareWrapper extends HttpServletRequestWrapper {
//~ Constructors ===================================================================================================
public SavedRequestAwareWrapper(SavedRequest saved, HttpServletRequest request) {
public SavedRequestAwareWrapper(DefaultSavedRequest saved, HttpServletRequest request) {
super(request);
savedRequest = saved;
@ -234,7 +234,7 @@ class SavedRequestAwareWrapper extends HttpServletRequestWrapper {
* In both cases the value from the wrapped request should be used.
* <p>
* If the value from the wrapped request is null, an attempt will be made to retrieve the parameter
* from the SavedRequest, if available..
* from the DefaultSavedRequest, if available..
*/
@Override
public String getParameter(String name) {

View File

@ -13,7 +13,7 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
/**
* The default implementation of {@link SessionAuthenticationStrategy}.
@ -45,7 +45,7 @@ public class DefaultSessionAuthenticationStrategy implements SessionAuthenticati
* In the case where the attributes will not be migrated, this field allows a list of named attributes
* which should <em>not</em> be discarded.
*/
private List<String> retainedAttributes = Arrays.asList(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
private List<String> retainedAttributes = Arrays.asList(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
/**
* If set to <tt>true</tt>, a session will always be created, even if one didn't exist at the start of the request.

View File

@ -42,7 +42,7 @@ import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.util.ThrowableAnalyzer;
/**
@ -66,9 +66,9 @@ public class ExceptionTranslationFilterTests {
return null;
}
SavedRequest savedRequest = (SavedRequest) session.getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
DefaultSavedRequest savedRequest = (DefaultSavedRequest) session.getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
return savedRequest.getFullRequestUrl();
return savedRequest.getRedirectUrl();
}
@Test
@ -199,7 +199,7 @@ public class ExceptionTranslationFilterTests {
doThrow(new BadCredentialsException("")).when(fc).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));
request.setMethod("POST");
filter.doFilter(request, new MockHttpServletResponse(), fc);
assertTrue(request.getSession().getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY) == null);
assertTrue(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY) == null);
}
@Test(expected=IllegalArgumentException.class)

View File

@ -49,7 +49,7 @@ import org.springframework.security.web.authentication.ExceptionMappingAuthentic
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.session.SessionAuthenticationStrategy;
@ -83,7 +83,7 @@ public class AbstractProcessingFilterTests extends TestCase {
filter.destroy();
}
private SavedRequest makeSavedRequestForUrl() {
private DefaultSavedRequest makeSavedRequestForUrl() {
MockHttpServletRequest request = createMockRequest();
request.setMethod("GET");
request.setServletPath("/some_protected_file.html");
@ -91,10 +91,10 @@ public class AbstractProcessingFilterTests extends TestCase {
request.setServerName("www.example.com");
request.setRequestURI("/mycontext/some_protected_file.html");
return new SavedRequest(request, new PortResolverImpl());
return new DefaultSavedRequest(request, new PortResolverImpl());
}
// private SavedRequest makePostSavedRequestForUrl() {
// private DefaultSavedRequest makePostSavedRequestForUrl() {
// MockHttpServletRequest request = createMockRequest();
// request.setServletPath("/some_protected_file.html");
// request.setScheme("http");
@ -102,7 +102,7 @@ public class AbstractProcessingFilterTests extends TestCase {
// request.setRequestURI("/mycontext/post/some_protected_file.html");
// request.setMethod("POST");
//
// return new SavedRequest(request, new PortResolverImpl());
// return new DefaultSavedRequest(request, new PortResolverImpl());
// }
protected void setUp() throws Exception {
@ -327,7 +327,7 @@ public class AbstractProcessingFilterTests extends TestCase {
throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, makeSavedRequestForUrl());
request.getSession().setAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, makeSavedRequestForUrl());
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
@ -352,7 +352,7 @@ public class AbstractProcessingFilterTests extends TestCase {
public void testSuccessfulAuthenticationCausesRedirectToSessionSpecifiedUrl() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, makeSavedRequestForUrl());
request.getSession().setAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, makeSavedRequestForUrl());
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
@ -367,7 +367,7 @@ public class AbstractProcessingFilterTests extends TestCase {
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals(makeSavedRequestForUrl().getFullRequestUrl(), response.getRedirectedUrl());
assertEquals(makeSavedRequestForUrl().getRedirectUrl(), response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
}

View File

@ -0,0 +1,33 @@
package org.springframework.security.web.savedrequest;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
*
* @author Luke Taylor
* @version $Id$
* @since 3.0
*/
public class HttpSessionRequestCacheTests {
@Test
public void originalGetRequestDoesntMatchIncomingPost() {
HttpSessionRequestCache cache = new HttpSessionRequestCache();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/destination");
MockHttpServletResponse response = new MockHttpServletResponse();
cache.saveRequest(request, response);
assertNotNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
assertNotNull(cache.getRequest(request, response));
MockHttpServletRequest newRequest = new MockHttpServletRequest("POST", "/destination");
newRequest.setSession(request.getSession());
assertNull(cache.getMatchingRequest(newRequest, response));
}
}

View File

@ -9,7 +9,6 @@ import org.springframework.mock.web.MockHttpServletResponse;
public class RequestCacheAwareFilterTests {
@Test
public void savedRequestIsRemovedAfterMatch() throws Exception {
RequestCacheAwareFilter filter = new RequestCacheAwareFilter();
@ -18,10 +17,9 @@ public class RequestCacheAwareFilterTests {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/destination");
MockHttpServletResponse response = new MockHttpServletResponse();
cache.saveRequest(request, response);
assertNotNull(request.getSession().getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
assertNotNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
filter.doFilter(request, response, new MockFilterChain());
assertNull(request.getSession().getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
assertNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
}
}

View File

@ -13,13 +13,13 @@ import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.PortResolverImpl;
import org.springframework.security.web.savedrequest.FastHttpDateFormat;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.savedrequest.SavedRequestAwareWrapper;
public class SavedRequestAwareWrapperTests {
private SavedRequestAwareWrapper createWrapper(MockHttpServletRequest requestToSave, MockHttpServletRequest requestToWrap) {
SavedRequest saved = requestToSave == null ? null : new SavedRequest(requestToSave, new PortResolverImpl());
DefaultSavedRequest saved = requestToSave == null ? null : new DefaultSavedRequest(requestToSave, new PortResolverImpl());
return new SavedRequestAwareWrapper(saved, requestToWrap);
}

View File

@ -4,7 +4,7 @@ import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.security.MockPortResolver;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.mock.web.MockHttpServletRequest;
/**
@ -16,7 +16,7 @@ public class SavedRequestTests {
public void headersAreCaseInsensitive() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("USER-aGenT", "Mozilla");
SavedRequest saved = new SavedRequest(request, new MockPortResolver(8080, 8443));
DefaultSavedRequest saved = new DefaultSavedRequest(request, new MockPortResolver(8080, 8443));
assertEquals("Mozilla", saved.getHeaderValues("user-agent").next());
}
@ -25,7 +25,7 @@ public class SavedRequestTests {
public void parametersAreCaseInsensitive() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("ThisIsATest", "Hi mom");
SavedRequest saved = new SavedRequest(request, new MockPortResolver(8080, 8443));
DefaultSavedRequest saved = new DefaultSavedRequest(request, new MockPortResolver(8080, 8443));
assertEquals("Hi mom", saved.getParameterValues("thisisatest")[0]);
}
}

View File

@ -10,7 +10,7 @@ import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
/**
*
@ -48,12 +48,12 @@ public class DefaultSessionAuthenticationStrategyTests {
HttpServletRequest request = new MockHttpServletRequest();
HttpSession session = request.getSession();
session.setAttribute("blah", "blah");
session.setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, "SavedRequest");
session.setAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, "DefaultSavedRequest");
strategy.onAuthentication(mock(Authentication.class), request, new MockHttpServletResponse());
assertNull(request.getSession().getAttribute("blah"));
assertNotNull(request.getSession().getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
assertNotNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY));
}
@Test