SEC-1052: Added "disableUrlRewriting" parameter to HttpSessionSecurityContextRepository.

This commit is contained in:
Luke Taylor 2008-12-16 17:35:34 +00:00
parent 717fdcfec3
commit b24cc17dea
4 changed files with 113 additions and 13 deletions

View File

@ -61,6 +61,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
private Object contextObject = new SecurityContextImpl();
private boolean cloneFromHttpSession = false;
private boolean allowSessionCreation = true;
private boolean disableUrlRewriting = false;
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
@ -234,6 +235,16 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
this.allowSessionCreation = allowSessionCreation;
}
/**
* Allows the use of session identifiers in URLs to be disabled. Off by default.
*
* @param disableUrlRewriting set to <tt>true</tt> to disable URL encoding methods in the response wrapper
* and prevent the use of <tt>jsessionid</tt> parameters.
*/
public void setDisableUrlRewriting(boolean disableUrlRewriting) {
this.disableUrlRewriting = disableUrlRewriting;
}
//~ Inner Classes ==================================================================================================
/**
@ -265,7 +276,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
SaveToSessionResponseWrapper(HttpServletResponse response, HttpServletRequest request,
boolean httpSessionExistedAtStartOfRequest,
int contextHashBeforeChainExecution) {
super(response);
super(response, disableUrlRewriting);
this.request = request;
this.httpSessionExistedAtStartOfRequest = httpSessionExistedAtStartOfRequest;
this.contextHashBeforeChainExecution = contextHashBeforeChainExecution;

View File

@ -8,21 +8,31 @@ import javax.servlet.http.HttpServletResponseWrapper;
/**
* Base class for response wrappers which encapsulate the logic for storing a security context and which
* store the with the <code>SecurityContext</code> when a <code>sendError()</code> or <code>sendRedirect</code>
* happens. See SEC-398.
* happens. See issue SEC-398.
* <p>
* Sub-classes should implement the {@link #saveContext(SecurityContext context)} method.
* <p>
* Support is also provided for disabling URL rewriting
*
* @author Luke Taylor
* @author Marten Algesten
* @version $Id$
* @since 2.5
*/
abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResponseWrapper {
public abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResponseWrapper {
boolean contextSaved = false;
private boolean contextSaved = false;
/* See SEC-1052 */
private boolean disableUrlRewriting;
SaveContextOnUpdateOrErrorResponseWrapper(HttpServletResponse response) {
/**
* @param response the response to be wrapped
* @param disableUrlRewriting turns the URL encoding methods into null operations, preventing the use
* of URL rewriting to add the session identifier as a URL parameter.
*/
public SaveContextOnUpdateOrErrorResponseWrapper(HttpServletResponse response, boolean disableUrlRewriting) {
super(response);
this.disableUrlRewriting = disableUrlRewriting;
}
/**
@ -36,7 +46,8 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
* Makes sure the session is updated before calling the
* superclass <code>sendError()</code>
*/
public void sendError(int sc) throws IOException {
@Override
public final void sendError(int sc) throws IOException {
doSaveContext();
super.sendError(sc);
}
@ -45,7 +56,8 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
* Makes sure the session is updated before calling the
* superclass <code>sendError()</code>
*/
public void sendError(int sc, String msg) throws IOException {
@Override
public final void sendError(int sc, String msg) throws IOException {
doSaveContext();
super.sendError(sc, msg);
}
@ -54,7 +66,8 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
* Makes sure the context is stored before calling the
* superclass <code>sendRedirect()</code>
*/
public void sendRedirect(String location) throws IOException {
@Override
public final void sendRedirect(String location) throws IOException {
doSaveContext();
super.sendRedirect(location);
}
@ -67,10 +80,42 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
contextSaved = true;
}
@Override
public final String encodeRedirectUrl(String url) {
if (disableUrlRewriting) {
return url;
}
return super.encodeRedirectUrl(url);
}
@Override
public final String encodeRedirectURL(String url) {
if (disableUrlRewriting) {
return url;
}
return super.encodeRedirectURL(url);
}
@Override
public final String encodeUrl(String url) {
if (disableUrlRewriting) {
return url;
}
return super.encodeUrl(url);
}
@Override
public final String encodeURL(String url) {
if (disableUrlRewriting) {
return url;
}
return super.encodeURL(url);
}
/**
* Tells if the response wrapper has called <code>saveContext()</code> because of an error or redirect.
*/
public boolean isContextSaved() {
public final boolean isContextSaved() {
return contextSaved;
}

View File

@ -1,10 +1,11 @@
<html>
<body>
Provides a "request context".
Classes related to the establishment of a security context for the duration of a request (such as
an HTTP or RMI invocation) and for the maintenance of the context between requests (by storing it in an HTTP sessio, for
example).
<p>
A request context is associated with the current execution thread. It holds
objects that would otherwise need to be included in many method signatures,
such as for authentication.</p>
A security context is associated with the current execution thread for the duration of the request, making the
authentication information it contains available throughout all the layers of an application.
</body>
</html>

View File

@ -161,6 +161,49 @@ public class HttpSessionSecurityContextRepositoryTests {
assertTrue(repo.generateNewContext() instanceof MockContext);
}
@Test
@SuppressWarnings("deprecation")
public void sessionDisableUrlRewritingPreventsSessionIdBeingWrittenToUrl() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
final String sessionId = ";jsessionid=id";
MockHttpServletResponse response = new MockHttpServletResponse() {
@Override
public String encodeRedirectUrl(String url) {
return url + sessionId;
}
@Override
public String encodeRedirectURL(String url) {
return url + sessionId;
}
@Override
public String encodeUrl(String url) {
return url + sessionId;
}
@Override
public String encodeURL(String url) {
return url + sessionId;
}
};
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
repo.loadContext(holder);
String url = "/aUrl";
assertEquals(url + sessionId, holder.getResponse().encodeRedirectUrl(url));
assertEquals(url + sessionId, holder.getResponse().encodeRedirectURL(url));
assertEquals(url + sessionId, holder.getResponse().encodeUrl(url));
assertEquals(url + sessionId, holder.getResponse().encodeURL(url));
repo.setDisableUrlRewriting(true);
holder = new HttpRequestResponseHolder(request, response);
repo.loadContext(holder);
assertEquals(url, holder.getResponse().encodeRedirectUrl(url));
assertEquals(url, holder.getResponse().encodeRedirectURL(url));
assertEquals(url, holder.getResponse().encodeUrl(url));
assertEquals(url, holder.getResponse().encodeURL(url));
}
static class MockContext implements Cloneable, SecurityContext {
Authentication a;