SEC-1697: Don't publish authorization success events in AbstractSecurityInterceptor by default.
This commit is contained in:
parent
74b0c1780e
commit
01c9c4e4db
|
@ -109,6 +109,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
|||
private boolean alwaysReauthenticate = false;
|
||||
private boolean rejectPublicInvocations = false;
|
||||
private boolean validateConfigAttributes = true;
|
||||
private boolean publishAuthorizationSuccess = false;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
|
@ -212,7 +213,9 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
|||
logger.debug("Authorization successful");
|
||||
}
|
||||
|
||||
if (publishAuthorizationSuccess) {
|
||||
publishEvent(new AuthorizedEvent(object, attributes, authenticated));
|
||||
}
|
||||
|
||||
// Attempt to run as a different user
|
||||
Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attributes);
|
||||
|
@ -402,6 +405,16 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
|||
this.messages = new MessageSourceAccessor(messageSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only {@code AuthorizationFailureEvent} will be published.
|
||||
* If you set this property to {@code true}, {@code AuthorizedEvent}s will also be published.
|
||||
*
|
||||
* @param publishAuthorizationSuccess default value is {@code false}
|
||||
*/
|
||||
public void setPublishAuthorizationSuccess(boolean publishAuthorizationSuccess) {
|
||||
this.publishAuthorizationSuccess = publishAuthorizationSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* By rejecting public invocations (and setting this property to <tt>true</tt>), essentially you are ensuring
|
||||
* that every secure object invocation advised by <code>AbstractSecurityInterceptor</code> has a configuration
|
||||
|
|
|
@ -26,12 +26,15 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.security.ITargetObject;
|
||||
import org.springframework.security.TargetObject;
|
||||
import org.springframework.security.access.AccessDecisionManager;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.access.event.AuthorizationFailureEvent;
|
||||
import org.springframework.security.access.event.AuthorizedEvent;
|
||||
import org.springframework.security.access.intercept.AfterInvocationManager;
|
||||
import org.springframework.security.access.intercept.RunAsManager;
|
||||
import org.springframework.security.access.intercept.RunAsUserToken;
|
||||
|
@ -58,6 +61,7 @@ public class MethodSecurityInterceptorTests {
|
|||
private AccessDecisionManager adm;
|
||||
private MethodSecurityMetadataSource mds;
|
||||
private AuthenticationManager authman;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
|
@ -69,9 +73,11 @@ public class MethodSecurityInterceptorTests {
|
|||
adm = mock(AccessDecisionManager.class);
|
||||
authman = mock(AuthenticationManager.class);
|
||||
mds = mock(MethodSecurityMetadataSource.class);
|
||||
eventPublisher = mock(ApplicationEventPublisher.class);
|
||||
interceptor.setAccessDecisionManager(adm);
|
||||
interceptor.setAuthenticationManager(authman);
|
||||
interceptor.setSecurityMetadataSource(mds);
|
||||
interceptor.setApplicationEventPublisher(eventPublisher);
|
||||
createTarget(false);
|
||||
}
|
||||
|
||||
|
@ -210,6 +216,7 @@ public class MethodSecurityInterceptorTests {
|
|||
@Test
|
||||
public void callSucceedsIfAccessDecisionManagerGrantsAccess() throws Exception {
|
||||
token.setAuthenticated(true);
|
||||
interceptor.setPublishAuthorizationSuccess(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(token);
|
||||
mdsReturnsUserRole();
|
||||
|
||||
|
@ -217,9 +224,10 @@ public class MethodSecurityInterceptorTests {
|
|||
|
||||
// Note we check the isAuthenticated remained true in following line
|
||||
assertEquals("hello org.springframework.security.authentication.TestingAuthenticationToken true", result);
|
||||
verify(eventPublisher).publishEvent(any(AuthorizedEvent.class));
|
||||
}
|
||||
|
||||
@Test(expected=AccessDeniedException.class)
|
||||
@Test
|
||||
public void callIsntMadeWhenAccessDecisionManagerRejectsAccess() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(token);
|
||||
// Use mocked target to make sure invocation doesn't happen (not in expectations so test would fail)
|
||||
|
@ -228,7 +236,12 @@ public class MethodSecurityInterceptorTests {
|
|||
when(authman.authenticate(token)).thenReturn(token);
|
||||
doThrow(new AccessDeniedException("rejected")).when(adm).decide(any(Authentication.class), any(MethodInvocation.class), any(List.class));
|
||||
|
||||
try {
|
||||
advisedTarget.makeUpperCase("HELLO");
|
||||
fail();
|
||||
} catch (AccessDeniedException expected) {
|
||||
}
|
||||
verify(eventPublisher).publishEvent(any(AuthorizationFailureEvent.class));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
|
|
|
@ -105,7 +105,8 @@ public class FilterSecurityInterceptorTests {
|
|||
|
||||
interceptor.invoke(fi);
|
||||
|
||||
verify(publisher).publishEvent(any(AuthorizedEvent.class));
|
||||
// SEC-1697
|
||||
verify(publisher, never()).publishEvent(any(AuthorizedEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue