diff --git a/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java b/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java index e86cbb6f21..b263230c18 100644 --- a/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java +++ b/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java @@ -40,6 +40,7 @@ import org.springframework.security.authentication.AuthenticationCredentialsNotF import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.SpringSecurityMessageSource; +import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.Assert; @@ -226,16 +227,18 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A } // no further work post-invocation - return new InterceptorStatusToken(authenticated, false, attributes, object); + return new InterceptorStatusToken(SecurityContextHolder.getContext(), false, attributes, object); } else { if (debug) { logger.debug("Switching to RunAs Authentication: " + runAs); } + SecurityContext origCtx = SecurityContextHolder.getContext(); + SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext()); SecurityContextHolder.getContext().setAuthentication(runAs); // need to revert to token.Authenticated post-invocation - return new InterceptorStatusToken(authenticated, true, attributes, object); + return new InterceptorStatusToken(origCtx, true, attributes, object); } } @@ -255,21 +258,22 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A if (token.isContextHolderRefreshRequired()) { if (logger.isDebugEnabled()) { - logger.debug("Reverting to original Authentication: " + token.getAuthentication().toString()); + logger.debug("Reverting to original Authentication: " + token.getSecurityContext().getAuthentication()); } - SecurityContextHolder.getContext().setAuthentication(token.getAuthentication()); + SecurityContextHolder.setContext(token.getSecurityContext()); } if (afterInvocationManager != null) { // Attempt after invocation handling try { - returnedObject = afterInvocationManager.decide(token.getAuthentication(), token.getSecureObject(), + returnedObject = afterInvocationManager.decide(token.getSecurityContext().getAuthentication(), + token.getSecureObject(), token.getAttributes(), returnedObject); } catch (AccessDeniedException accessDeniedException) { - AuthorizationFailureEvent event = new AuthorizationFailureEvent(token.getSecureObject(), - token.getAttributes(), token.getAuthentication(), accessDeniedException); + AuthorizationFailureEvent event = new AuthorizationFailureEvent(token.getSecureObject(), token + .getAttributes(), token.getSecurityContext().getAuthentication(), accessDeniedException); publishEvent(event); throw accessDeniedException; diff --git a/core/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java b/core/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java index de6042601c..4102e52298 100644 --- a/core/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java +++ b/core/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java @@ -19,6 +19,7 @@ import java.util.Collection; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; /** @@ -33,16 +34,16 @@ import org.springframework.security.core.Authentication; public class InterceptorStatusToken { //~ Instance fields ================================================================================================ - private final Authentication authentication; - private final Collection attr; - private final Object secureObject; - private final boolean contextHolderRefreshRequired; + private SecurityContext securityContext; + private Collection attr; + private Object secureObject; + private boolean contextHolderRefreshRequired; //~ Constructors =================================================================================================== - public InterceptorStatusToken(Authentication authentication, boolean contextHolderRefreshRequired, + public InterceptorStatusToken(SecurityContext securityContext, boolean contextHolderRefreshRequired, Collection attributes, Object secureObject) { - this.authentication = authentication; + this.securityContext = securityContext; this.contextHolderRefreshRequired = contextHolderRefreshRequired; this.attr = attributes; this.secureObject = secureObject; @@ -54,8 +55,8 @@ public class InterceptorStatusToken { return attr; } - public Authentication getAuthentication() { - return authentication; + public SecurityContext getSecurityContext() { + return securityContext; } public Object getSecureObject() { diff --git a/core/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java b/core/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java index 6e696c0b20..dc32e4d27e 100644 --- a/core/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java +++ b/core/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java @@ -15,8 +15,7 @@ package org.springframework.security.access.intercept; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.util.List; @@ -24,8 +23,8 @@ import org.aopalliance.intercept.MethodInvocation; import org.junit.Test; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; -import org.springframework.security.access.intercept.InterceptorStatusToken; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.util.SimpleMethodInvocation; @@ -40,12 +39,12 @@ public class InterceptorStatusTokenTests { public void testOperation() { List attr = SecurityConfig.createList("FOO"); MethodInvocation mi = new SimpleMethodInvocation(); - InterceptorStatusToken token = new InterceptorStatusToken(new UsernamePasswordAuthenticationToken("rod", - "koala"), true, attr, mi); + SecurityContext ctx = SecurityContextHolder.createEmptyContext(); + InterceptorStatusToken token = new InterceptorStatusToken(ctx, true, attr, mi); assertTrue(token.isContextHolderRefreshRequired()); assertEquals(attr, token.getAttributes()); assertEquals(mi, token.getSecureObject()); - assertEquals("rod", token.getAuthentication().getPrincipal()); + assertSame(ctx, token.getSecurityContext()); } } diff --git a/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java b/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java index 0c7a120c7c..9f5f54b784 100644 --- a/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java +++ b/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java @@ -19,12 +19,8 @@ import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import java.util.*; - import org.aopalliance.intercept.MethodInvocation; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.*; import org.springframework.aop.framework.ProxyFactory; import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.ITargetObject; @@ -45,8 +41,11 @@ import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import java.util.*; + /** * Tests {@link MethodSecurityInterceptor}. * @@ -251,7 +250,8 @@ public class MethodSecurityInterceptorTests { @Test public void runAsReplacementIsCorrectlySet() throws Exception { - SecurityContextHolder.getContext().setAuthentication(token); + SecurityContext ctx = SecurityContextHolder.getContext(); + ctx.setAuthentication(token); token.setAuthenticated(true); final RunAsManager runAs = mock(RunAsManager.class); final RunAsUserToken runAsToken = @@ -263,7 +263,8 @@ public class MethodSecurityInterceptorTests { String result = advisedTarget.makeUpperCase("hello"); assertEquals("HELLO org.springframework.security.access.intercept.RunAsUserToken true", result); // Check we've changed back - assertEquals(token, SecurityContextHolder.getContext().getAuthentication()); + assertSame(ctx, SecurityContextHolder.getContext()); + assertSame(token, SecurityContextHolder.getContext().getAuthentication()); } @Test(expected=AuthenticationCredentialsNotFoundException.class)