SEC-398: Lazy update of 'filterApplied' to true

This commit is contained in:
Vishal Puri 2007-07-25 05:34:40 +00:00
parent 99cc55b94a
commit bc30b903f8
2 changed files with 419 additions and 283 deletions

View File

@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.web.util.WebUtils;
/** /**
* Populates the {@link SecurityContextHolder} with information obtained from * Populates the {@link SecurityContextHolder} with information obtained from
@ -94,13 +95,15 @@ import org.springframework.util.ReflectionUtils;
* @author Ben Alex * @author Ben Alex
* @author Patrick Burleson * @author Patrick Burleson
* @version $Id: HttpSessionContextIntegrationFilter.java 1784 2007-02-24 * @version $Id: HttpSessionContextIntegrationFilter.java 1784 2007-02-24
* 21:00:24Z luke_t $ * 21:00:24Z luke_t $
*/ */
public class HttpSessionContextIntegrationFilter implements InitializingBean, Filter { public class HttpSessionContextIntegrationFilter implements InitializingBean,
Filter {
// ~ Static fields/initializers // ~ Static fields/initializers
// ===================================================================================== // =====================================================================================
protected static final Log logger = LogFactory.getLog(HttpSessionContextIntegrationFilter.class); protected static final Log logger = LogFactory
.getLog(HttpSessionContextIntegrationFilter.class);
static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied"; static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied";
@ -172,13 +175,16 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
// ======================================================================================================== // ========================================================================================================
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) { if ((this.context == null)
throw new IllegalArgumentException("context must be defined and implement SecurityContext " || (!SecurityContext.class.isAssignableFrom(this.context))) {
+ "(typically use org.acegisecurity.context.SecurityContextImpl; existing class is " + this.context throw new IllegalArgumentException(
+ ")"); "context must be defined and implement SecurityContext "
+ "(typically use org.acegisecurity.context.SecurityContextImpl; existing class is "
+ this.context + ")");
} }
if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) { if ((forceEagerSessionCreation == true)
&& (allowSessionCreation == false)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true"); "If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
} }
@ -190,59 +196,60 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
public void destroy() { public void destroy() {
} }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, public void doFilter(ServletRequest request, ServletResponse response,
ServletException { FilterChain chain) throws IOException, ServletException {
boolean filterApplied = false; boolean filterApplied = false;
if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) { if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {
// ensure that filter is only applied once per request // ensure that filter is only applied once per request
System.out.println("Filter already applied so moving on");
chain.doFilter(request, response); chain.doFilter(request, response);
} } else {
else {
if (request != null) {
filterApplied = true;
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
HttpSession httpSession = null; HttpSession httpSession = null;
boolean httpSessionExistedAtStartOfRequest = false; boolean httpSessionExistedAtStartOfRequest = false;
try { try {
httpSession = ((HttpServletRequest) request).getSession(forceEagerSessionCreation); httpSession = ((HttpServletRequest) request)
} .getSession(forceEagerSessionCreation);
catch (IllegalStateException ignored) { } catch (IllegalStateException ignored) {
} }
if (httpSession != null) { if (httpSession != null) {
httpSessionExistedAtStartOfRequest = true; httpSessionExistedAtStartOfRequest = true;
Object contextFromSessionObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY); Object contextFromSessionObject = httpSession
.getAttribute(ACEGI_SECURITY_CONTEXT_KEY);
if (contextFromSessionObject != null) { if (contextFromSessionObject != null) {
// Clone if required (see SEC-356) // Clone if required (see SEC-356)
if (cloneFromHttpSession) { if (cloneFromHttpSession) {
Assert.isInstanceOf(Cloneable.class, contextFromSessionObject, Assert
"Context must implement Clonable and provide a Object.clone() method"); .isInstanceOf(Cloneable.class,
contextFromSessionObject,
"Context must implement Clonable and provide a Object.clone() method");
try { try {
Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {}); Method m = contextFromSessionObject.getClass()
.getMethod("clone", new Class[] {});
if (!m.isAccessible()) { if (!m.isAccessible()) {
m.setAccessible(true); m.setAccessible(true);
} }
contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {}); contextFromSessionObject = m.invoke(
} contextFromSessionObject, new Object[] {});
catch (Exception ex) { } catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex); ReflectionUtils.handleReflectionException(ex);
} }
} }
if (contextFromSessionObject instanceof SecurityContext) { if (contextFromSessionObject instanceof SecurityContext) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Obtained from ACEGI_SECURITY_CONTEXT a valid SecurityContext and " logger
+ "set to SecurityContextHolder: '" + contextFromSessionObject + "'"); .debug("Obtained from ACEGI_SECURITY_CONTEXT a valid SecurityContext and "
+ "set to SecurityContextHolder: '"
+ contextFromSessionObject + "'");
} }
SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject); SecurityContextHolder
} .setContext((SecurityContext) contextFromSessionObject);
else { } else {
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled()) {
logger logger
.warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '" .warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
@ -255,60 +262,66 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
SecurityContextHolder.setContext(generateNewContext()); SecurityContextHolder.setContext(generateNewContext());
} }
} } else {
else {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("HttpSession returned null object for ACEGI_SECURITY_CONTEXT - new " logger
+ "SecurityContext instance associated with SecurityContextHolder"); .debug("HttpSession returned null object for ACEGI_SECURITY_CONTEXT - new "
+ "SecurityContext instance associated with SecurityContextHolder");
} }
SecurityContextHolder.setContext(generateNewContext()); SecurityContextHolder.setContext(generateNewContext());
} }
}
else { } else {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("No HttpSession currently exists - new SecurityContext instance " logger
+ "associated with SecurityContextHolder"); .debug("No HttpSession currently exists - new SecurityContext instance "
+ "associated with SecurityContextHolder");
} }
SecurityContextHolder.setContext(generateNewContext()); SecurityContextHolder.setContext(generateNewContext());
} }
// end synch
// Make the HttpSession null, as we want to ensure we don't keep // Make the HttpSession null, as we want to ensure we don't keep
// a reference to the HttpSession laying around in case the // a reference to the HttpSession laying around in case the
// chain.doFilter() invalidates it. // chain.doFilter() invalidates it.
httpSession = null; httpSession = null;
// Proceed with chain // Proceed with chain
int contextWhenChainProceeded = SecurityContextHolder.getContext().hashCode(); int contextWhenChainProceeded = SecurityContextHolder.getContext()
.hashCode();
try { try {
filterApplied = true;
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
chain.doFilter(request, response); chain.doFilter(request, response);
} } catch (IOException ioe) {
catch (IOException ioe) {
throw ioe; throw ioe;
} } catch (ServletException se) {
catch (ServletException se) {
throw se; throw se;
} } finally {
finally {
// do clean up, even if there was an exception // do clean up, even if there was an exception
// Store context back to HttpSession // Store context back to HttpSession
try { try {
httpSession = ((HttpServletRequest) request).getSession(false); httpSession = ((HttpServletRequest) request)
} .getSession(false);
catch (IllegalStateException ignored) { } catch (IllegalStateException ignored) {
} }
if ((httpSession == null) && httpSessionExistedAtStartOfRequest) { if ((httpSession == null) && httpSessionExistedAtStartOfRequest) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("HttpSession is now null, but was not null at start of request; " logger
+ "session was invalidated, so do not create a new session"); .debug("HttpSession is now null, but was not null at start of request; "
+ "session was invalidated, so do not create a new session");
} }
} }
// Generate a HttpSession only if we need to // Generate a HttpSession only if we need to
if ((httpSession == null) && !httpSessionExistedAtStartOfRequest) { if ((httpSession == null)
&& !httpSessionExistedAtStartOfRequest) {
if (!allowSessionCreation) { if (!allowSessionCreation) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger logger
@ -317,23 +330,24 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
+ "(because the allowSessionCreation property is false) - SecurityContext thus not " + "(because the allowSessionCreation property is false) - SecurityContext thus not "
+ "stored for next request"); + "stored for next request");
} }
} } else if (!contextObject.equals(SecurityContextHolder
else if (!contextObject.equals(SecurityContextHolder.getContext())) { .getContext())) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("HttpSession being created as SecurityContextHolder contents are non-default"); logger
.debug("HttpSession being created as SecurityContextHolder contents are non-default");
} }
try { try {
httpSession = ((HttpServletRequest) request).getSession(true); httpSession = ((HttpServletRequest) request)
.getSession(true);
} catch (IllegalStateException ignored) {
} }
catch (IllegalStateException ignored) { } else {
}
}
else {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger logger
.debug("HttpSession is null, but SecurityContextHolder has not changed from default: ' " .debug("HttpSession is null, but SecurityContextHolder has not changed from default: ' "
+ SecurityContextHolder.getContext() + SecurityContextHolder
.getContext()
+ "'; not creating HttpSession or storing SecurityContextHolder contents"); + "'; not creating HttpSession or storing SecurityContextHolder contents");
} }
} }
@ -345,36 +359,39 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
// actually changed (see JIRA SEC-37) // actually changed (see JIRA SEC-37)
if ((httpSession != null) if ((httpSession != null)
&& (SecurityContextHolder.getContext().hashCode() != contextWhenChainProceeded)) { && (SecurityContextHolder.getContext().hashCode() != contextWhenChainProceeded)) {
httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY,
SecurityContextHolder.getContext());
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("SecurityContext stored to HttpSession: '" + SecurityContextHolder.getContext() logger.debug("SecurityContext stored to HttpSession: '"
+ "'"); + SecurityContextHolder.getContext() + "'");
} }
} }
if (filterApplied) { if (filterApplied) {
request.removeAttribute(FILTER_APPLIED); request.removeAttribute(FILTER_APPLIED);
} }
// Remove SecurityContextHolder contents // Remove SecurityContextHolder contents
SecurityContextHolder.clearContext(); SecurityContextHolder.clearContext();
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("SecurityContextHolder set to new context, as request processing completed"); logger
.debug("SecurityContextHolder set to new context, as request processing completed");
} }
} }
} }
} }
public SecurityContext generateNewContext() throws ServletException { public SecurityContext generateNewContext() throws ServletException {
try { try {
return (SecurityContext) this.context.newInstance(); return (SecurityContext) this.context.newInstance();
} } catch (InstantiationException ie) {
catch (InstantiationException ie) {
throw new ServletException(ie); throw new ServletException(ie);
} } catch (IllegalAccessException iae) {
catch (IllegalAccessException iae) {
throw new ServletException(iae); throw new ServletException(iae);
} }
} }
@ -386,9 +403,11 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
/** /**
* Does nothing. We use IoC container lifecycle services instead. * Does nothing. We use IoC container lifecycle services instead.
* *
* @param filterConfig ignored * @param filterConfig
* ignored
* *
* @throws ServletException ignored * @throws ServletException
* ignored
*/ */
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
} }

View File

@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.MockFilterConfig; import org.acegisecurity.MockFilterConfig;
import org.acegisecurity.adapters.PrincipalAcegiUserToken; import org.acegisecurity.adapters.PrincipalAcegiUserToken;
import org.jmock.Mock;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
@ -36,271 +37,387 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
/** /**
* Tests {@link HttpSessionContextIntegrationFilter}. * Tests {@link HttpSessionContextIntegrationFilter}.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id: HttpSessionContextIntegrationFilterTests.java 1858 2007-05-24
* 02:04:47Z benalex $
*/ */
public class HttpSessionContextIntegrationFilterTests extends TestCase { public class HttpSessionContextIntegrationFilterTests extends TestCase {
//~ Constructors =================================================================================================== // ~ Constructors
// ===================================================================================================
public HttpSessionContextIntegrationFilterTests() { public HttpSessionContextIntegrationFilterTests() {
super(); super();
} }
public HttpSessionContextIntegrationFilterTests(String arg0) { public HttpSessionContextIntegrationFilterTests(String arg0) {
super(arg0); super(arg0);
} }
//~ Methods ======================================================================================================== // ~ Methods
// ========================================================================================================
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, private static void executeFilterInContainerSimulator(
ServletResponse response, FilterChain filterChain) FilterConfig filterConfig, Filter filter, ServletRequest request,
throws ServletException, IOException { ServletResponse response, FilterChain filterChain)
filter.init(filterConfig); throws ServletException, IOException {
filter.doFilter(request, response, filterChain); filter.init(filterConfig);
filter.destroy(); filter.doFilter(request, response, filterChain);
} filter.destroy();
}
public static void main(String[] args) { public static void main(String[] args) {
junit.textui.TestRunner.run(HttpSessionContextIntegrationFilterTests.class); junit.textui.TestRunner
} .run(HttpSessionContextIntegrationFilterTests.class);
}
public void testDetectsIncompatibleSessionProperties() public void testDetectsIncompatibleSessionProperties() throws Exception {
throws Exception { HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
try { try {
filter.setAllowSessionCreation(false); filter.setAllowSessionCreation(false);
filter.setForceEagerSessionCreation(true); filter.setForceEagerSessionCreation(true);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException"); fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertTrue(true); assertTrue(true);
} }
filter.setAllowSessionCreation(true); filter.setAllowSessionCreation(true);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
assertTrue(true); assertTrue(true);
} }
public void testDetectsMissingOrInvalidContext() throws Exception { public void testDetectsMissingOrInvalidContext() throws Exception {
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
try { try {
filter.setContext(null); filter.setContext(null);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException"); fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertTrue(true); assertTrue(true);
} }
try { try {
filter.setContext(Integer.class); filter.setContext(Integer.class);
assertEquals(Integer.class, filter.getContext()); assertEquals(Integer.class, filter.getContext());
filter.afterPropertiesSet(); filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException"); fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertTrue(true); assertTrue(true);
} }
} }
public void testExceptionWithinFilterChainStillClearsSecurityContextHolder() public void testExceptionWithinFilterChainStillClearsSecurityContextHolder()
throws Exception { throws Exception {
// Build an Authentication object we simulate came from HttpSession // Build an Authentication object we simulate came from HttpSession
PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken(
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null); "key",
"someone",
"password",
new GrantedAuthority[] { new GrantedAuthorityImpl("SOME_ROLE") },
null);
// Build a Context to store in HttpSession (simulating prior request) // Build a Context to store in HttpSession (simulating prior request)
SecurityContext sc = new SecurityContextImpl(); SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(sessionPrincipal); sc.setAuthentication(sessionPrincipal);
// Build a mock request // Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession().setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, sc); request.getSession().setAttribute(
HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
sc);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(sessionPrincipal, null, new IOException()); FilterChain chain = new MockFilterChain(sessionPrincipal, null,
new IOException());
// Prepare filter // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class); filter.setContext(SecurityContextImpl.class);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
// Execute filter // Execute filter
try { try {
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); executeFilterInContainerSimulator(new MockFilterConfig(), filter,
fail("We should have received the IOException thrown inside the filter chain here"); request, response, chain);
} catch (IOException ioe) { fail("We should have received the IOException thrown inside the filter chain here");
assertTrue(true); } catch (IOException ioe) {
} assertTrue(true);
}
// Check the SecurityContextHolder is null, even though an exception was thrown during chain // Check the SecurityContextHolder is null, even though an exception was
assertEquals(new SecurityContextImpl(), SecurityContextHolder.getContext()); // thrown during chain
assertNull("Should have cleared FILTER_APPLIED", request.getAttribute(HttpSessionContextIntegrationFilter.FILTER_APPLIED)); assertEquals(new SecurityContextImpl(), SecurityContextHolder
} .getContext());
assertNull(
"Should have cleared FILTER_APPLIED",
request
.getAttribute(HttpSessionContextIntegrationFilter.FILTER_APPLIED));
}
public void testExistingContextContentsCopiedIntoContextHolderFromSessionAndChangesToContextCopiedBackToSession() public void testExistingContextContentsCopiedIntoContextHolderFromSessionAndChangesToContextCopiedBackToSession()
throws Exception { throws Exception {
// Build an Authentication object we simulate came from HttpSession // Build an Authentication object we simulate came from HttpSession
PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken(
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null); "key",
"someone",
"password",
new GrantedAuthority[] { new GrantedAuthorityImpl("SOME_ROLE") },
null);
// Build an Authentication object we simulate our Authentication changed it to // Build an Authentication object we simulate our Authentication changed
PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", // it to
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, null); PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken(
"key", "someone", "password",
new GrantedAuthority[] { new GrantedAuthorityImpl(
"SOME_DIFFERENT_ROLE") }, null);
// Build a Context to store in HttpSession (simulating prior request) // Build a Context to store in HttpSession (simulating prior request)
SecurityContext sc = new SecurityContextImpl(); SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(sessionPrincipal); sc.setAuthentication(sessionPrincipal);
// Build a mock request // Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession().setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, sc); request.getSession().setAttribute(
HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
sc);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(sessionPrincipal, updatedPrincipal, null); FilterChain chain = new MockFilterChain(sessionPrincipal,
updatedPrincipal, null);
// Prepare filter // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class); filter.setContext(SecurityContextImpl.class);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
// Execute filter // Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession // Obtain new/update Authentication from HttpSession
SecurityContext context = (SecurityContext) request.getSession() SecurityContext context = (SecurityContext) request
.getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); .getSession()
assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication()); .getAttribute(
} HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal, ((SecurityContext) context)
.getAuthentication());
}
public void testHttpSessionCreatedWhenContextHolderChanges() public void testHttpSessionCreatedWhenContextHolderChanges()
throws Exception { throws Exception {
// Build an Authentication object we simulate our Authentication changed it to // Build an Authentication object we simulate our Authentication changed
PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", // it to
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, null); PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken(
"key", "someone", "password",
new GrantedAuthority[] { new GrantedAuthorityImpl(
"SOME_DIFFERENT_ROLE") }, null);
// Build a mock request // Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, updatedPrincipal, null); FilterChain chain = new MockFilterChain(null, updatedPrincipal, null);
// Prepare filter // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class); filter.setContext(SecurityContextImpl.class);
// don't call afterPropertiesSet to test case when not instantiated by Spring // don't call afterPropertiesSet to test case when not instantiated by
//filter.afterPropertiesSet(); // Spring
// filter.afterPropertiesSet();
// Execute filter // Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/updated Authentication from HttpSession // Obtain new/updated Authentication from HttpSession
SecurityContext context = (SecurityContext) request.getSession(false) SecurityContext context = (SecurityContext) request
.getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); .getSession(false)
assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication()); .getAttribute(
} HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal, ((SecurityContext) context)
.getAuthentication());
}
public void testHttpSessionEagerlyCreatedWhenDirected() public void testHttpSessionEagerlyCreatedWhenDirected() throws Exception {
throws Exception { // Build a mock request
// Build a mock request MockHttpServletRequest request = new MockHttpServletRequest(null, null);
MockHttpServletRequest request = new MockHttpServletRequest(null, null); MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain chain = new MockFilterChain(null, null, null);
FilterChain chain = new MockFilterChain(null, null, null);
// Prepare filter // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class); filter.setContext(SecurityContextImpl.class);
filter.setForceEagerSessionCreation(true); // non-default filter.setForceEagerSessionCreation(true); // non-default
filter.afterPropertiesSet(); filter.afterPropertiesSet();
// Execute filter // Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Check the session is not null // Check the session is not null
assertNotNull(request.getSession(false)); assertNotNull(request.getSession(false));
} }
public void testHttpSessionNotCreatedUnlessContextHolderChanges() public void testHttpSessionNotCreatedUnlessContextHolderChanges()
throws Exception { throws Exception {
// Build a mock request // Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(null, null); MockHttpServletRequest request = new MockHttpServletRequest(null, null);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, null, null); FilterChain chain = new MockFilterChain(null, null, null);
// Prepare filter // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class); filter.setContext(SecurityContextImpl.class);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
// Execute filter // Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Check the session is null // Check the session is null
assertNull(request.getSession(false)); assertNull(request.getSession(false));
} }
public void testHttpSessionWithNonContextInWellKnownLocationIsOverwritten() public void testHttpSessionWithNonContextInWellKnownLocationIsOverwritten()
throws Exception { throws Exception {
// Build an Authentication object we simulate our Authentication changed it to // Build an Authentication object we simulate our Authentication changed
PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key", "someone", "password", // it to
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")}, null); PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken(
"key", "someone", "password",
new GrantedAuthority[] { new GrantedAuthorityImpl(
"SOME_DIFFERENT_ROLE") }, null);
// Build a mock request // Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession() request.getSession().setAttribute(
.setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY, "NOT_A_CONTEXT_OBJECT"); HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
"NOT_A_CONTEXT_OBJECT");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, updatedPrincipal, null); FilterChain chain = new MockFilterChain(null, updatedPrincipal, null);
// Prepare filter // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter(); HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class); filter.setContext(SecurityContextImpl.class);
filter.afterPropertiesSet(); filter.afterPropertiesSet();
// Execute filter // Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain); executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession // Obtain new/update Authentication from HttpSession
SecurityContext context = (SecurityContext) request.getSession() SecurityContext context = (SecurityContext) request
.getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY); .getSession()
assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication()); .getAttribute(
} HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal, ((SecurityContext) context)
.getAuthentication());
}
//~ Inner Classes ================================================================================================== public void testConcurrentThreadsLazilyChangeFilterAppliedValueToTrue()
throws Exception {
PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken(
"key",
"someone",
"password",
new GrantedAuthority[] { new GrantedAuthorityImpl("SOME_ROLE") },
null);
private class MockFilterChain extends TestCase implements FilterChain { // Build a Context to store in HttpSession (simulating prior request)
private Authentication changeContextHolder; SecurityContext sc = new SecurityContextImpl();
private Authentication expectedOnContextHolder; sc.setAuthentication(sessionPrincipal);
private IOException toThrowDuringChain;
public MockFilterChain(Authentication expectedOnContextHolder, Authentication changeContextHolder, MockHttpServletRequest request = new MockHttpServletRequest();
IOException toThrowDuringChain) { request.getSession().setAttribute(
this.expectedOnContextHolder = expectedOnContextHolder; HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
this.changeContextHolder = changeContextHolder; sc);
this.toThrowDuringChain = toThrowDuringChain; MockHttpServletResponse response = new MockHttpServletResponse();
}
private MockFilterChain() {} // Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecurityContextImpl.class);
filter.afterPropertiesSet();
public void doFilter(ServletRequest arg0, ServletResponse arg1) for (int i = 0; i < 3; i++) {
throws IOException, ServletException { ThreadRunner runner = new ThreadRunner(request, response, filter,
if (expectedOnContextHolder != null) { new MockFilterChain(sessionPrincipal, null, null));
assertEquals(expectedOnContextHolder, SecurityContextHolder.getContext().getAuthentication()); runner.start();
} }
if (changeContextHolder != null) { }
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(changeContextHolder);
SecurityContextHolder.setContext(sc);
}
if (toThrowDuringChain != null) { // ~ Inner Classes
throw toThrowDuringChain; // ==================================================================================================
}
} private class MockFilterChain extends TestCase implements FilterChain {
} private Authentication changeContextHolder;
private Authentication expectedOnContextHolder;
private IOException toThrowDuringChain;
public MockFilterChain(Authentication expectedOnContextHolder,
Authentication changeContextHolder,
IOException toThrowDuringChain) {
this.expectedOnContextHolder = expectedOnContextHolder;
this.changeContextHolder = changeContextHolder;
this.toThrowDuringChain = toThrowDuringChain;
}
private MockFilterChain() {
}
public void doFilter(ServletRequest arg0, ServletResponse arg1)
throws IOException, ServletException {
if (expectedOnContextHolder != null) {
assertEquals(expectedOnContextHolder, SecurityContextHolder
.getContext().getAuthentication());
}
if (changeContextHolder != null) {
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(changeContextHolder);
SecurityContextHolder.setContext(sc);
}
if (toThrowDuringChain != null) {
throw toThrowDuringChain;
}
}
}
private static class ThreadRunner extends Thread {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private HttpSessionContextIntegrationFilter filter;
private MockFilterChain chain;
public ThreadRunner(MockHttpServletRequest request,
MockHttpServletResponse response,
HttpSessionContextIntegrationFilter filter,
MockFilterChain chain) {
this.request = request;
this.response = response;
this.filter = filter;
this.chain = chain;
}
public void run() {
try {
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(),
filter, request, response, chain);
// Check the session is not null
assertNotNull(request.getSession(false));
} catch (Exception e) {
e.printStackTrace();
}
}
}
} }