mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-24 04:52:16 +00:00
SEC-1750: Make sure RunAs replacement is constrained to the SecurityContext of the current thread.
This commit is contained in:
parent
a24570ae06
commit
887e3361d2
@ -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;
|
||||
|
||||
@ -224,16 +225,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,21 +256,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);
|
||||
.getAttributes(), token.getSecurityContext().getAuthentication(), accessDeniedException);
|
||||
publishEvent(event);
|
||||
|
||||
throw accessDeniedException;
|
||||
|
@ -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 Authentication authentication;
|
||||
private SecurityContext securityContext;
|
||||
private Collection<ConfigAttribute> attr;
|
||||
private Object secureObject;
|
||||
private boolean contextHolderRefreshRequired;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public InterceptorStatusToken(Authentication authentication, boolean contextHolderRefreshRequired,
|
||||
public InterceptorStatusToken(SecurityContext securityContext, boolean contextHolderRefreshRequired,
|
||||
Collection<ConfigAttribute> 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() {
|
||||
|
@ -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<ConfigAttribute> 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());
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
|
||||
package org.springframework.security.access.intercept.aopalliance;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -44,6 +43,7 @@ import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
@ -276,7 +276,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 = jmock.mock(RunAsManager.class);
|
||||
final RunAsUserToken runAsToken =
|
||||
@ -292,7 +293,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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user