SEC-1052: Added "disableUrlRewriting" parameter to HttpSessionSecurityContextRepository.
This commit is contained in:
parent
717fdcfec3
commit
b24cc17dea
|
@ -61,6 +61,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
private Object contextObject = new SecurityContextImpl();
|
private Object contextObject = new SecurityContextImpl();
|
||||||
private boolean cloneFromHttpSession = false;
|
private boolean cloneFromHttpSession = false;
|
||||||
private boolean allowSessionCreation = true;
|
private boolean allowSessionCreation = true;
|
||||||
|
private boolean disableUrlRewriting = false;
|
||||||
|
|
||||||
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
|
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
|
||||||
|
|
||||||
|
@ -234,6 +235,16 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
this.allowSessionCreation = allowSessionCreation;
|
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 ==================================================================================================
|
//~ Inner Classes ==================================================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -265,7 +276,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
|
||||||
SaveToSessionResponseWrapper(HttpServletResponse response, HttpServletRequest request,
|
SaveToSessionResponseWrapper(HttpServletResponse response, HttpServletRequest request,
|
||||||
boolean httpSessionExistedAtStartOfRequest,
|
boolean httpSessionExistedAtStartOfRequest,
|
||||||
int contextHashBeforeChainExecution) {
|
int contextHashBeforeChainExecution) {
|
||||||
super(response);
|
super(response, disableUrlRewriting);
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.httpSessionExistedAtStartOfRequest = httpSessionExistedAtStartOfRequest;
|
this.httpSessionExistedAtStartOfRequest = httpSessionExistedAtStartOfRequest;
|
||||||
this.contextHashBeforeChainExecution = contextHashBeforeChainExecution;
|
this.contextHashBeforeChainExecution = contextHashBeforeChainExecution;
|
||||||
|
|
|
@ -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
|
* 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>
|
* 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>
|
* <p>
|
||||||
* Sub-classes should implement the {@link #saveContext(SecurityContext context)} method.
|
* Sub-classes should implement the {@link #saveContext(SecurityContext context)} method.
|
||||||
|
* <p>
|
||||||
|
* Support is also provided for disabling URL rewriting
|
||||||
*
|
*
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @author Marten Algesten
|
* @author Marten Algesten
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
* @since 2.5
|
* @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);
|
super(response);
|
||||||
|
this.disableUrlRewriting = disableUrlRewriting;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +46,8 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
|
||||||
* Makes sure the session is updated before calling the
|
* Makes sure the session is updated before calling the
|
||||||
* superclass <code>sendError()</code>
|
* superclass <code>sendError()</code>
|
||||||
*/
|
*/
|
||||||
public void sendError(int sc) throws IOException {
|
@Override
|
||||||
|
public final void sendError(int sc) throws IOException {
|
||||||
doSaveContext();
|
doSaveContext();
|
||||||
super.sendError(sc);
|
super.sendError(sc);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +56,8 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
|
||||||
* Makes sure the session is updated before calling the
|
* Makes sure the session is updated before calling the
|
||||||
* superclass <code>sendError()</code>
|
* 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();
|
doSaveContext();
|
||||||
super.sendError(sc, msg);
|
super.sendError(sc, msg);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +66,8 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
|
||||||
* Makes sure the context is stored before calling the
|
* Makes sure the context is stored before calling the
|
||||||
* superclass <code>sendRedirect()</code>
|
* superclass <code>sendRedirect()</code>
|
||||||
*/
|
*/
|
||||||
public void sendRedirect(String location) throws IOException {
|
@Override
|
||||||
|
public final void sendRedirect(String location) throws IOException {
|
||||||
doSaveContext();
|
doSaveContext();
|
||||||
super.sendRedirect(location);
|
super.sendRedirect(location);
|
||||||
}
|
}
|
||||||
|
@ -67,10 +80,42 @@ abstract class SaveContextOnUpdateOrErrorResponseWrapper extends HttpServletResp
|
||||||
contextSaved = true;
|
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.
|
* 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;
|
return contextSaved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<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>
|
<p>
|
||||||
A request context is associated with the current execution thread. It holds
|
A security context is associated with the current execution thread for the duration of the request, making the
|
||||||
objects that would otherwise need to be included in many method signatures,
|
authentication information it contains available throughout all the layers of an application.
|
||||||
such as for authentication.</p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,49 @@ public class HttpSessionSecurityContextRepositoryTests {
|
||||||
assertTrue(repo.generateNewContext() instanceof MockContext);
|
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 {
|
static class MockContext implements Cloneable, SecurityContext {
|
||||||
Authentication a;
|
Authentication a;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue