mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-09 11:53:30 +00:00
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
|
* Provides security interception of AspectJ method invocations.
|
||||||
* by this security interceptor is of type {@link MethodDefinitionSource}. This is shared with the AOP Alliance based
|
* <p>
|
||||||
* security interceptor (<code>MethodSecurityInterceptor</code>), since both work with Java <code>Method</code>s.</p>
|
* The <code>ObjectDefinitionSource</code> required by this security interceptor is of type
|
||||||
* <p>The secure object type is <code>org.aspectj.lang.JoinPoint</code>, which is passed from the relevant
|
* {@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
|
* <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>
|
* AspectJCallback} which contains the call for AspectJ to continue processing: <code>return proceed();</code>.
|
||||||
* <P>Refer to {@link AbstractSecurityInterceptor} for details on the workflow.</p>
|
* <p>
|
||||||
|
* Refer to {@link AbstractSecurityInterceptor} for details on the workflow.
|
||||||
*
|
*
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
@ -42,10 +46,6 @@ public class AspectJSecurityInterceptor extends AbstractSecurityInterceptor {
|
|||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
public MethodDefinitionSource getObjectDefinitionSource() {
|
|
||||||
return this.objectDefinitionSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<? extends Object> getSecureObjectClass() {
|
public Class<? extends Object> getSecureObjectClass() {
|
||||||
return JoinPoint.class;
|
return JoinPoint.class;
|
||||||
}
|
}
|
||||||
|
@ -15,26 +15,26 @@
|
|||||||
|
|
||||||
package org.springframework.security.intercept.method.aspectj;
|
package org.springframework.security.intercept.method.aspectj;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
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.After;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.security.AccessDecisionManager;
|
||||||
import org.springframework.security.AccessDeniedException;
|
import org.springframework.security.AccessDeniedException;
|
||||||
import org.springframework.security.GrantedAuthority;
|
import org.springframework.security.AuthenticationManager;
|
||||||
import org.springframework.security.GrantedAuthorityImpl;
|
import org.springframework.security.ITargetObject;
|
||||||
import org.springframework.security.MockAccessDecisionManager;
|
|
||||||
import org.springframework.security.MockApplicationEventPublisher;
|
|
||||||
import org.springframework.security.MockAuthenticationManager;
|
|
||||||
import org.springframework.security.MockJoinPoint;
|
import org.springframework.security.MockJoinPoint;
|
||||||
import org.springframework.security.MockRunAsManager;
|
import org.springframework.security.SecurityConfig;
|
||||||
import org.springframework.security.TargetObject;
|
import org.springframework.security.TargetObject;
|
||||||
import org.springframework.security.context.SecurityContextHolder;
|
import org.springframework.security.context.SecurityContextHolder;
|
||||||
import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource;
|
import org.springframework.security.intercept.method.MethodDefinitionSource;
|
||||||
import org.springframework.security.intercept.method.MethodDefinitionSourceEditor;
|
|
||||||
import org.springframework.security.providers.TestingAuthenticationToken;
|
import org.springframework.security.providers.TestingAuthenticationToken;
|
||||||
import org.springframework.security.util.AuthorityUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,93 +44,64 @@ import org.springframework.security.util.AuthorityUtils;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class AspectJSecurityInterceptorTests {
|
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 ========================================================================================================
|
//~ 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
|
@After
|
||||||
public void clearContext() {
|
public void clearContext() {
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCallbackIsInvokedWhenPermissionGranted() throws Exception {
|
public void callbackIsInvokedWhenPermissionGranted() throws Exception {
|
||||||
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
jmock.checking(new Expectations() {{
|
||||||
si.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
|
oneOf(mds).getAttributes(with(any(JoinPoint.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
oneOf(authman).authenticate(token); will(returnValue(token));
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
oneOf(adm).decide(with(token), with(aNonNull(JoinPoint.class)), with(aNonNull(List.class)));
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
oneOf(aspectJCallback).proceedWithObject();
|
||||||
|
}});
|
||||||
|
|
||||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
editor.setAsText("org.springframework.security.TargetObject.countLength=MOCK_ONE,MOCK_TWO");
|
interceptor.invoke(joinPoint, aspectJCallback);
|
||||||
|
jmock.assertIsSatisfied();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=AccessDeniedException.class)
|
@Test(expected=AccessDeniedException.class)
|
||||||
public void testCallbackIsNotInvokedWhenPermissionDenied() throws Exception {
|
public void callbackIsNotInvokedWhenPermissionDenied() throws Exception {
|
||||||
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
jmock.checking(new Expectations() {{
|
||||||
si.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
|
oneOf(mds).getAttributes(with(any(JoinPoint.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
oneOf(authman).authenticate(token); will(returnValue(token));
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
oneOf(adm).decide(with(token), with(aNonNull(JoinPoint.class)), with(aNonNull(List.class)));
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
will(throwException(new AccessDeniedException("denied")));
|
||||||
|
never(aspectJCallback).proceedWithObject();
|
||||||
|
}});
|
||||||
|
|
||||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
editor.setAsText("org.springframework.security.TargetObject.countLength=MOCK_ONE,MOCK_TWO");
|
interceptor.invoke(joinPoint, aspectJCallback);
|
||||||
|
jmock.assertIsSatisfied();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user