This commit is contained in:
parent
7505b734d6
commit
f3387cd879
|
@ -24,13 +24,17 @@ import org.aspectj.lang.JoinPoint;
|
|||
|
||||
|
||||
/**
|
||||
* Provides security interception of AspectJ method invocations.<p>The <code>ObjectDefinitionSource</code> required
|
||||
* by this security interceptor is of type {@link MethodDefinitionSource}. This is shared with the AOP Alliance based
|
||||
* security interceptor (<code>MethodSecurityInterceptor</code>), since both work with Java <code>Method</code>s.</p>
|
||||
* <p>The secure object type is <code>org.aspectj.lang.JoinPoint</code>, which is passed from the relevant
|
||||
* Provides security interception of AspectJ method invocations.
|
||||
* <p>
|
||||
* The <code>ObjectDefinitionSource</code> required by this security interceptor is of type
|
||||
* {@link MethodDefinitionSource}. This is shared with the AOP Alliance based security interceptor
|
||||
* (<code>MethodSecurityInterceptor</code>), since both work with Java <code>Method</code>s.
|
||||
* <p>
|
||||
* The secure object type is <code>org.aspectj.lang.JoinPoint</code>, which is passed from the relevant
|
||||
* <code>around()</code> advice. The <code>around()</code> advice also passes an anonymous implementation of {@link
|
||||
* AspectJCallback} which contains the call for AspectJ to continue processing: <code>return proceed();</code>.</p>
|
||||
* <P>Refer to {@link AbstractSecurityInterceptor} for details on the workflow.</p>
|
||||
* AspectJCallback} which contains the call for AspectJ to continue processing: <code>return proceed();</code>.
|
||||
* <p>
|
||||
* Refer to {@link AbstractSecurityInterceptor} for details on the workflow.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
|
@ -42,10 +46,6 @@ public class AspectJSecurityInterceptor extends AbstractSecurityInterceptor {
|
|||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public MethodDefinitionSource getObjectDefinitionSource() {
|
||||
return this.objectDefinitionSource;
|
||||
}
|
||||
|
||||
public Class<? extends Object> getSecureObjectClass() {
|
||||
return JoinPoint.class;
|
||||
}
|
||||
|
|
|
@ -15,26 +15,26 @@
|
|||
|
||||
package org.springframework.security.intercept.method.aspectj;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.AccessDecisionManager;
|
||||
import org.springframework.security.AccessDeniedException;
|
||||
import org.springframework.security.GrantedAuthority;
|
||||
import org.springframework.security.GrantedAuthorityImpl;
|
||||
import org.springframework.security.MockAccessDecisionManager;
|
||||
import org.springframework.security.MockApplicationEventPublisher;
|
||||
import org.springframework.security.MockAuthenticationManager;
|
||||
import org.springframework.security.AuthenticationManager;
|
||||
import org.springframework.security.ITargetObject;
|
||||
import org.springframework.security.MockJoinPoint;
|
||||
import org.springframework.security.MockRunAsManager;
|
||||
import org.springframework.security.SecurityConfig;
|
||||
import org.springframework.security.TargetObject;
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource;
|
||||
import org.springframework.security.intercept.method.MethodDefinitionSourceEditor;
|
||||
import org.springframework.security.intercept.method.MethodDefinitionSource;
|
||||
import org.springframework.security.providers.TestingAuthenticationToken;
|
||||
import org.springframework.security.util.AuthorityUtils;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -44,93 +44,64 @@ import org.springframework.security.util.AuthorityUtils;
|
|||
* @version $Id$
|
||||
*/
|
||||
public class AspectJSecurityInterceptorTests {
|
||||
private Mockery jmock = new JUnit4Mockery();
|
||||
private TestingAuthenticationToken token;
|
||||
private AspectJSecurityInterceptor interceptor;
|
||||
private AccessDecisionManager adm;
|
||||
private MethodDefinitionSource mds;
|
||||
private AuthenticationManager authman;
|
||||
private AspectJCallback aspectJCallback;
|
||||
private JoinPoint joinPoint;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public final void setUp() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
token = new TestingAuthenticationToken("Test", "Password");
|
||||
interceptor = new AspectJSecurityInterceptor();
|
||||
adm = jmock.mock(AccessDecisionManager.class);
|
||||
authman = jmock.mock(AuthenticationManager.class);
|
||||
mds = jmock.mock(MethodDefinitionSource.class);
|
||||
interceptor.setAccessDecisionManager(adm);
|
||||
interceptor.setAuthenticationManager(authman);
|
||||
interceptor.setObjectDefinitionSource(mds);
|
||||
Method method = TargetObject.class.getMethod("countLength", new Class[] {String.class});
|
||||
joinPoint = new MockJoinPoint(new TargetObject(), method);
|
||||
aspectJCallback = jmock.mock(AspectJCallback.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallbackIsInvokedWhenPermissionGranted() throws Exception {
|
||||
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
||||
si.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
|
||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||
si.setRunAsManager(new MockRunAsManager());
|
||||
public void callbackIsInvokedWhenPermissionGranted() throws Exception {
|
||||
jmock.checking(new Expectations() {{
|
||||
oneOf(mds).getAttributes(with(any(JoinPoint.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
|
||||
oneOf(authman).authenticate(token); will(returnValue(token));
|
||||
oneOf(adm).decide(with(token), with(aNonNull(JoinPoint.class)), with(aNonNull(List.class)));
|
||||
oneOf(aspectJCallback).proceedWithObject();
|
||||
}});
|
||||
|
||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
||||
editor.setAsText("org.springframework.security.TargetObject.countLength=MOCK_ONE,MOCK_TWO");
|
||||
|
||||
MapBasedMethodDefinitionSource map = (MapBasedMethodDefinitionSource) editor.getValue();
|
||||
si.setObjectDefinitionSource(map);
|
||||
assertEquals(map, si.getObjectDefinitionSource());
|
||||
|
||||
si.afterPropertiesSet();
|
||||
|
||||
Class<TargetObject> clazz = TargetObject.class;
|
||||
Method method = clazz.getMethod("countLength", new Class[] {String.class});
|
||||
MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method);
|
||||
|
||||
MockAspectJCallback aspectJCallback = new MockAspectJCallback();
|
||||
|
||||
SecurityContextHolder.getContext()
|
||||
.setAuthentication(new TestingAuthenticationToken("rod", "koala",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_ONE")}));
|
||||
|
||||
Object result = si.invoke(joinPoint, aspectJCallback);
|
||||
|
||||
assertEquals("object proceeded", result);
|
||||
SecurityContextHolder.getContext().setAuthentication(token);
|
||||
interceptor.invoke(joinPoint, aspectJCallback);
|
||||
jmock.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test(expected=AccessDeniedException.class)
|
||||
public void testCallbackIsNotInvokedWhenPermissionDenied() throws Exception {
|
||||
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
||||
si.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
|
||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||
si.setRunAsManager(new MockRunAsManager());
|
||||
public void callbackIsNotInvokedWhenPermissionDenied() throws Exception {
|
||||
jmock.checking(new Expectations() {{
|
||||
oneOf(mds).getAttributes(with(any(JoinPoint.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
|
||||
oneOf(authman).authenticate(token); will(returnValue(token));
|
||||
oneOf(adm).decide(with(token), with(aNonNull(JoinPoint.class)), with(aNonNull(List.class)));
|
||||
will(throwException(new AccessDeniedException("denied")));
|
||||
never(aspectJCallback).proceedWithObject();
|
||||
}});
|
||||
|
||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
||||
editor.setAsText("org.springframework.security.TargetObject.countLength=MOCK_ONE,MOCK_TWO");
|
||||
|
||||
MapBasedMethodDefinitionSource map = (MapBasedMethodDefinitionSource) editor.getValue();
|
||||
si.setObjectDefinitionSource(map);
|
||||
|
||||
si.afterPropertiesSet();
|
||||
|
||||
Class<TargetObject> clazz = TargetObject.class;
|
||||
Method method = clazz.getMethod("countLength", new Class[] {String.class});
|
||||
MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method);
|
||||
|
||||
MockAspectJCallback aspectJCallback = new MockAspectJCallback();
|
||||
aspectJCallback.setThrowExceptionIfInvoked(true);
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES ));
|
||||
|
||||
si.invoke(joinPoint, aspectJCallback);
|
||||
fail("Should have thrown AccessDeniedException");
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockAspectJCallback implements AspectJCallback {
|
||||
private boolean throwExceptionIfInvoked = false;
|
||||
|
||||
private MockAspectJCallback() {}
|
||||
|
||||
public Object proceedWithObject() {
|
||||
if (throwExceptionIfInvoked) {
|
||||
throw new IllegalStateException("AspectJCallback proceeded");
|
||||
}
|
||||
|
||||
return "object proceeded";
|
||||
}
|
||||
|
||||
public void setThrowExceptionIfInvoked(boolean throwExceptionIfInvoked) {
|
||||
this.throwExceptionIfInvoked = throwExceptionIfInvoked;
|
||||
}
|
||||
SecurityContextHolder.getContext().setAuthentication(token);
|
||||
interceptor.invoke(joinPoint, aspectJCallback);
|
||||
jmock.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue