Преглед на файлове

Converted MethodSecurityInterceptorTests to use mocks and deleted app context file.

Luke Taylor преди 17 години
родител
ревизия
a318aacc4f

+ 9 - 8
core/src/main/java/org/springframework/security/ConfigAttribute.java

@@ -23,10 +23,9 @@ import java.io.Serializable;
  *
  * <p>
  * When an {@link org.springframework.security.intercept.AbstractSecurityInterceptor}
- * is setup, a list of configuration attributes is defined for secure object
- * patterns. These configuration attributes have special meaning to a {@link
- * RunAsManager}, {@link AccessDecisionManager} or
- * <code>AccessDecisionManager</code> delegate.
+ * is set up, a list of configuration attributes is defined for secure object
+ * patterns. These configuration attributes have special meaning to a {@link RunAsManager},
+ * {@link AccessDecisionManager} or <code>AccessDecisionManager</code> delegate.
  *
  * <p>
  * Stored at runtime with other <code>ConfigAttribute</code>s for the same secure object target.
@@ -41,10 +40,12 @@ public interface ConfigAttribute extends Serializable {
      * If the <code>ConfigAttribute</code> can be represented as a <code>String</code> and that
      * <code>String</code> is sufficient in precision to be relied upon as a configuration parameter by a {@link
      * RunAsManager}, {@link AccessDecisionManager} or <code>AccessDecisionManager</code> delegate, this method should
-     * return such a <code>String</code>.<p>If the <code>ConfigAttribute</code> cannot be expressed with
-     * sufficient precision as a <code>String</code>,  <code>null</code> should be returned. Returning
-     * <code>null</code> will require any relying classes to specifically support the  <code>ConfigAttribute</code>
-     * implementation, so returning  <code>null</code> should be avoided unless actually  required.</p>
+     * return such a <code>String</code>.
+     * <p>
+     * If the <code>ConfigAttribute</code> cannot be expressed with sufficient precision as a <code>String</code>,
+     * <code>null</code> should be returned. Returning <code>null</code> will require any relying classes to
+     * specifically support the <code>ConfigAttribute</code> implementation, so returning <code>null</code> should
+     * be avoided unless actually required.
      *
      * @return a representation of the configuration attribute (or <code>null</code> if the configuration attribute
      *         cannot be expressed as a <code>String</code> with sufficient precision).

+ 219 - 300
core/src/test/java/org/springframework/security/intercept/method/aopalliance/MethodSecurityInterceptorTests.java

@@ -15,35 +15,45 @@
 
 package org.springframework.security.intercept.method.aopalliance;
 
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.List;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-import junit.framework.TestCase;
+import java.util.List;
 
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.aopalliance.intercept.MethodInvocation;
+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.aop.framework.ProxyFactory;
 import org.springframework.security.AccessDecisionManager;
 import org.springframework.security.AccessDeniedException;
 import org.springframework.security.AfterInvocationManager;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationCredentialsNotFoundException;
 import org.springframework.security.AuthenticationException;
+import org.springframework.security.AuthenticationManager;
+import org.springframework.security.BadCredentialsException;
 import org.springframework.security.ConfigAttribute;
 import org.springframework.security.GrantedAuthority;
 import org.springframework.security.GrantedAuthorityImpl;
 import org.springframework.security.ITargetObject;
 import org.springframework.security.MockAccessDecisionManager;
-import org.springframework.security.MockAfterInvocationManager;
 import org.springframework.security.MockAuthenticationManager;
 import org.springframework.security.MockRunAsManager;
 import org.springframework.security.RunAsManager;
+import org.springframework.security.SecurityConfig;
+import org.springframework.security.TargetObject;
 import org.springframework.security.context.SecurityContextHolder;
 import org.springframework.security.intercept.method.MethodDefinitionSource;
 import org.springframework.security.intercept.method.MockMethodDefinitionSource;
+import org.springframework.security.providers.TestingAuthenticationToken;
 import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
 import org.springframework.security.runas.RunAsManagerImpl;
-
+import org.springframework.security.runas.RunAsUserToken;
 
 /**
  * Tests {@link MethodSecurityInterceptor}.
@@ -51,356 +61,265 @@ import org.springframework.security.runas.RunAsManagerImpl;
  * @author Ben Alex
  * @version $Id$
  */
-public class MethodSecurityInterceptorTests extends TestCase {
-    //~ Constructors ===================================================================================================
-
-    public MethodSecurityInterceptorTests() {
-        super();
-    }
-
-    public MethodSecurityInterceptorTests(String arg0) {
-        super(arg0);
-    }
+public class MethodSecurityInterceptorTests {
+    private Mockery jmock = new JUnit4Mockery();
+    private TestingAuthenticationToken token;
+    private MethodSecurityInterceptor interceptor;
+    private ITargetObject realTarget;
+    private ITargetObject advisedTarget;
+    private AccessDecisionManager adm;
+    private MethodDefinitionSource mds;
+    private AuthenticationManager authman;
+
+    private Expectations mdsWillReturnNullFromGetAttributes;
+    private Expectations mdsWillReturnROLE_USERFromGetAttributes;
 
     //~ Methods ========================================================================================================
 
+    @Before
     public final void setUp() throws Exception {
-        super.setUp();
         SecurityContextHolder.clearContext();
+        token = new TestingAuthenticationToken("Test", "Password");
+        interceptor = new MethodSecurityInterceptor();
+        adm = jmock.mock(AccessDecisionManager.class);
+        authman = jmock.mock(AuthenticationManager.class);
+        mds = jmock.mock(MethodDefinitionSource.class);
+        interceptor.setAccessDecisionManager(adm);
+        interceptor.setAuthenticationManager(authman);
+        interceptor.setObjectDefinitionSource(mds);
+        createTarget(false);
+
+        mdsWillReturnNullFromGetAttributes = new Expectations() {{
+            oneOf(mds).getAttributes(with(any(MethodInvocation.class))); will (returnValue(null));
+        }};
+        mdsWillReturnROLE_USERFromGetAttributes = new Expectations() {{
+            oneOf(mds).getAttributes(with(any(MethodInvocation.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
+        }};
     }
 
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
         SecurityContextHolder.clearContext();
     }
 
-    private ITargetObject makeInterceptedTarget() {
-        ApplicationContext context = new ClassPathXmlApplicationContext(
-                "org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
-
-        return (ITargetObject) context.getBean("target");
+    private void createTarget(boolean useMock) {
+        realTarget = useMock ? jmock.mock(ITargetObject.class) : new TargetObject();
+        ProxyFactory pf = new ProxyFactory(realTarget);
+        pf.addAdvice(interceptor);
+        advisedTarget = (ITargetObject) pf.getProxy();
     }
 
-    private ITargetObject makeInterceptedTargetRejectsAuthentication() {
-        ApplicationContext context = new ClassPathXmlApplicationContext(
-                "org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
-
-        MockAuthenticationManager authenticationManager = new MockAuthenticationManager(false);
-        MethodSecurityInterceptor si = (MethodSecurityInterceptor) context.getBean("securityInterceptor");
-        si.setAuthenticationManager(authenticationManager);
-
-        return (ITargetObject) context.getBean("target");
+    @Test
+    public void gettersReturnExpectedData() {
+        RunAsManager runAs = jmock.mock(RunAsManager.class);
+        AfterInvocationManager aim = jmock.mock(AfterInvocationManager.class);
+        interceptor.setRunAsManager(runAs);
+        interceptor.setAfterInvocationManager(aim);
+        assertEquals(adm, interceptor.getAccessDecisionManager());
+        assertEquals(runAs, interceptor.getRunAsManager());
+        assertEquals(authman, interceptor.getAuthenticationManager());
+        assertEquals(mds, interceptor.getObjectDefinitionSource());
+        assertEquals(aim, interceptor.getAfterInvocationManager());
     }
 
-    private ITargetObject makeInterceptedTargetWithoutAnAfterInvocationManager() {
-        ApplicationContext context = new ClassPathXmlApplicationContext(
-                "org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
-
-        MethodSecurityInterceptor si = (MethodSecurityInterceptor) context.getBean("securityInterceptor");
-        si.setAfterInvocationManager(null);
-
-        return (ITargetObject) context.getBean("target");
+    @Test(expected=IllegalArgumentException.class)
+    public void missingAccessDecisionManagerIsDetected() throws Exception {
+        interceptor.setAccessDecisionManager(null);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testCallingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts()
-        throws Exception {
-        ITargetObject target = makeInterceptedTarget();
-        String result = target.publicMakeLowerCase("HELLO");
-        assertEquals("hello Authentication empty", result);
+    @Test(expected=IllegalArgumentException.class)
+    public void missingAuthenticationManagerIsDetected() throws Exception {
+        interceptor.setAuthenticationManager(null);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillNotChangeItsIsAuthenticatedProperty()
-        throws Exception {
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password");
-        assertTrue(!token.isAuthenticated());
-        SecurityContextHolder.getContext().setAuthentication(token);
-
-        // The associated MockAuthenticationManager WILL accept the above UsernamePasswordAuthenticationToken
-        ITargetObject target = makeInterceptedTarget();
-        String result = target.publicMakeLowerCase("HELLO");
-        assertEquals("hello org.springframework.security.providers.UsernamePasswordAuthenticationToken false", result);
+    @Test(expected=IllegalArgumentException.class)
+    public void missingMethodDefinitionSourceIsRejected() throws Exception {
+        interceptor.setObjectDefinitionSource(null);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testDeniesWhenAppropriate() throws Exception {
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
-                new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_NO_BENEFIT_TO_THIS_GRANTED_AUTHORITY")});
-        SecurityContextHolder.getContext().setAuthentication(token);
-
-        ITargetObject target = makeInterceptedTarget();
-
-        try {
-            target.makeUpperCase("HELLO");
-            fail("Should have thrown AccessDeniedException");
-        } catch (AccessDeniedException expected) {
-            assertTrue(true);
-        }
+    @Test(expected=IllegalArgumentException.class)
+    public void missingRunAsManagerIsRejected() throws Exception {
+        interceptor.setRunAsManager(null);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testGetters() {
-        MockAccessDecisionManager accessDecision = new MockAccessDecisionManager();
-        MockRunAsManager runAs = new MockRunAsManager();
-        MockAuthenticationManager authManager = new MockAuthenticationManager();
-        MockMethodDefinitionSource methodSource = new MockMethodDefinitionSource(false, true);
-        MockAfterInvocationManager afterInvocation = new MockAfterInvocationManager();
-
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(accessDecision);
-        si.setRunAsManager(runAs);
-        si.setAuthenticationManager(authManager);
-        si.setObjectDefinitionSource(methodSource);
-        si.setAfterInvocationManager(afterInvocation);
-
-        assertEquals(accessDecision, si.getAccessDecisionManager());
-        assertEquals(runAs, si.getRunAsManager());
-        assertEquals(authManager, si.getAuthenticationManager());
-        assertEquals(methodSource, si.getObjectDefinitionSource());
-        assertEquals(afterInvocation, si.getAfterInvocationManager());
+    @Test(expected=IllegalArgumentException.class)
+    public void initializationRejectsObjectDefinitionSourceThatDoesNotSupportMethodInvocation() throws Throwable {
+        jmock.checking(new Expectations() {{
+           oneOf(mds).supports(MethodInvocation.class); will(returnValue(false));
+        }});
+        interceptor.afterPropertiesSet();
     }
 
-    public void testMethodCallWithRunAsReplacement() throws Exception {
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
-                new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_UPPER")});
-        SecurityContextHolder.getContext().setAuthentication(token);
-
-        ITargetObject target = makeInterceptedTarget();
-        String result = target.makeUpperCase("hello");
-        assertEquals("HELLO org.springframework.security.MockRunAsAuthenticationToken true", result);
+    @Test(expected=IllegalArgumentException.class)
+    public void initializationRejectsAccessDecisionManagerThatDoesNotSupportMethodInvocation() throws Exception {
+        jmock.checking(new Expectations() {{
+            oneOf(mds).supports(MethodInvocation.class); will(returnValue(true));
+            oneOf(adm).supports(MethodInvocation.class); will(returnValue(false));
+         }});
+         interceptor.afterPropertiesSet();
     }
 
-    public void testMethodCallWithoutRunAsReplacement()
-        throws Exception {
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
-                new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")});
-        assertTrue(token.isAuthenticated());
-        SecurityContextHolder.getContext().setAuthentication(token);
-
-        ITargetObject target = makeInterceptedTargetWithoutAnAfterInvocationManager();
-        String result = target.makeLowerCase("HELLO");
-
-        // Note we check the isAuthenticated remained true in following line
-        assertEquals("hello org.springframework.security.providers.UsernamePasswordAuthenticationToken true", result);
+    @Test(expected=IllegalArgumentException.class)
+    public void intitalizationRejectsRunAsManagerThatDoesNotSupportMethodInvocation() throws Exception {
+        final RunAsManager ram = jmock.mock(RunAsManager.class);
+        jmock.checking(new Expectations() {{
+            ignoring(mds);
+            oneOf(ram).supports(MethodInvocation.class); will(returnValue(false));
+        }});
+        interceptor.setRunAsManager(ram);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testRejectionOfEmptySecurityContext() throws Exception {
-        ITargetObject target = makeInterceptedTarget();
-
-        try {
-            target.makeUpperCase("hello");
-            fail("Should have thrown AuthenticationCredentialsNotFoundException");
-        } catch (AuthenticationCredentialsNotFoundException expected) {
-            assertTrue(true);
-        }
+    @Test(expected=IllegalArgumentException.class)
+    public void intitalizationRejectsAfterInvocationManagerThatDoesNotSupportMethodInvocation() throws Exception {
+        final AfterInvocationManager aim = jmock.mock(AfterInvocationManager.class);
+        jmock.checking(new Expectations() {{
+            oneOf(aim).supports(MethodInvocation.class); will(returnValue(false));
+            ignoring(anything());
+        }});
+        interceptor.setAfterInvocationManager(aim);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
-        si.setRunAsManager(new MockRunAsManager());
-
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("AccessDecisionManager does not support secure object class: interface org.aopalliance.intercept.MethodInvocation",
-                expected.getMessage());
-        }
+    @Test(expected=IllegalArgumentException.class)
+    public void initializationFailsIfAccessDecisionManagerRejectsConfigAttributes() throws Exception {
+        jmock.checking(new Expectations() {{
+            oneOf(adm).supports(with(aNonNull(ConfigAttribute.class))); will(returnValue(false));
+            ignoring(anything());
+        }});
+        interceptor.afterPropertiesSet();
     }
 
-    public void testRejectsCallsWhenAuthenticationIsIncorrect()
-        throws Exception {
-        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password");
-        assertTrue(!token.isAuthenticated());
-        SecurityContextHolder.getContext().setAuthentication(token);
-
-        // NB: The associated MockAuthenticationManager WILL reject the above UsernamePasswordAuthenticationToken
-        ITargetObject target = makeInterceptedTargetRejectsAuthentication();
-
-        try {
-            target.makeLowerCase("HELLO");
-            fail("Should have thrown AuthenticationException");
-        } catch (AuthenticationException expected) {
-            assertTrue(true);
-        }
+    @Test
+    public void validationNotAttemptedIfIsValidateConfigAttributesSetToFalse() throws Exception {
+        jmock.checking(new Expectations() {{
+            oneOf(mds).supports(MethodInvocation.class); will(returnValue(true));
+            oneOf(adm).supports(MethodInvocation.class); will(returnValue(true));
+            never(mds).getAllConfigAttributes();
+            never(adm).supports(with(any(ConfigAttribute.class)));
+        }});
+        interceptor.setValidateConfigAttributes(false);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
-        throws Throwable {
-        MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
-        interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings());
-        interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
-        interceptor.setAuthenticationManager(new MockAuthenticationManager());
-        interceptor.setRunAsManager(new MockRunAsManager());
-
-        try {
-            interceptor.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("ObjectDefinitionSource does not support secure object class: interface org.aopalliance.intercept.MethodInvocation",
-                expected.getMessage());
-        }
+    @Test
+    public void validationNotAttemptedIfMethodDefinitionSourceReturnsNullForAttributes() throws Exception {
+        jmock.checking(new Expectations() {{
+            oneOf(mds).supports(MethodInvocation.class); will(returnValue(true));
+            oneOf(adm).supports(MethodInvocation.class); will(returnValue(true));
+            oneOf(mds).getAllConfigAttributes(); will(returnValue(null));
+            never(adm).supports(with(any(ConfigAttribute.class)));
+        }});
+        interceptor.setValidateConfigAttributes(true);
+        interceptor.afterPropertiesSet();
     }
 
-    public void testRejectsCallsWhenObjectIsNull() throws Throwable {
-        MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
-
-        try {
-            interceptor.invoke(null);
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("Object was null", expected.getMessage());
-        }
+    @Test
+    public void callingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts() {
+        jmock.checking(mdsWillReturnNullFromGetAttributes);
+        String result = advisedTarget.publicMakeLowerCase("HELLO");
+        assertEquals("hello Authentication empty", result);
+        jmock.assertIsSatisfied();
     }
 
-    public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
-        si.setRunAsManager(new MockRunAsManagerWhichOnlySupportsStrings());
-        si.setAfterInvocationManager(new MockAfterInvocationManager());
-
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("RunAsManager does not support secure object class: interface org.aopalliance.intercept.MethodInvocation",
-                expected.getMessage());
-        }
+    @Test
+    public void callingAPublicMethodWhenPresentingAnAuthenticationObjectDoesntChangeItsAuthenticatedProperty() {
+        jmock.checking(mdsWillReturnNullFromGetAttributes);
+        SecurityContextHolder.getContext().setAuthentication(token);
+        assertEquals("hello org.springframework.security.providers.TestingAuthenticationToken false",
+                advisedTarget.publicMakeLowerCase("HELLO"));
+        assertTrue(!token.isAuthenticated());
     }
 
-    public void testStartupCheckForAccessDecisionManager()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setRunAsManager(new MockRunAsManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-        si.setAfterInvocationManager(new MockAfterInvocationManager());
+    @Test(expected=AuthenticationException.class)
+    public void callIsWhenAuthenticationManagerRejectsAuthentication() throws Exception {
+        final TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password");
+        SecurityContextHolder.getContext().setAuthentication(token);
 
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
+        jmock.checking(mdsWillReturnROLE_USERFromGetAttributes);
+        jmock.checking(new Expectations() {{
+            oneOf(authman).authenticate(token); will(throwException(new BadCredentialsException("rejected")));
+        }});
 
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("An AccessDecisionManager is required", expected.getMessage());
-        }
+        advisedTarget.makeLowerCase("HELLO");
     }
 
-    public void testStartupCheckForAuthenticationManager()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setRunAsManager(new MockRunAsManager());
-        si.setAfterInvocationManager(new MockAfterInvocationManager());
-
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
+    @Test
+    public void callSucceedsIfAccessDecisionManagerGrantsAccess() throws Exception {
+        token.setAuthenticated(true);
+        SecurityContextHolder.getContext().setAuthentication(token);
+        jmock.checking(mdsWillReturnROLE_USERFromGetAttributes);
+        jmock.checking(new Expectations() {{
+           oneOf(adm).decide(with(token), with(aNonNull(MethodInvocation.class)), with(aNonNull(List.class)));
+        }});
 
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("An AuthenticationManager is required", expected.getMessage());
-        }
-    }
+        String result = advisedTarget.makeLowerCase("HELLO");
 
-    public void testStartupCheckForMethodDefinitionSource()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("An ObjectDefinitionSource is required", expected.getMessage());
-        }
+        // Note we check the isAuthenticated remained true in following line
+        assertEquals("hello org.springframework.security.providers.TestingAuthenticationToken true", result);
     }
 
-    public void testStartupCheckForRunAsManager() throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-        si.setRunAsManager(null); // Overriding the default
-
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
-
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("A RunAsManager is required", expected.getMessage());
-        }
+    @Test(expected=AccessDeniedException.class)
+    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)
+        createTarget(true);
+        jmock.checking(mdsWillReturnROLE_USERFromGetAttributes);
+        jmock.checking(new Expectations() {{
+            oneOf(authman).authenticate(token); will(returnValue(token));
+            oneOf(adm).decide(with(token), with(aNonNull(MethodInvocation.class)), with(aNonNull(List.class)));
+            will(throwException(new AccessDeniedException("rejected")));
+        }});
+
+        advisedTarget.makeUpperCase("HELLO");
     }
 
-    public void testStartupCheckForValidAfterInvocationManager()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setRunAsManager(new MockRunAsManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-        si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings());
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
-
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue(expected.getMessage().startsWith("AfterInvocationManager does not support secure object class:"));
-        }
+    @Test(expected=IllegalArgumentException.class)
+    public void rejectsNullSecuredObjects() throws Throwable {
+        interceptor.invoke(null);
     }
 
-    public void testValidationFailsIfInvalidAttributePresented() throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-        si.setRunAsManager(new RunAsManagerImpl());
-
-        assertTrue(si.isValidateConfigAttributes()); // check default
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(true, true));
-
-        try {
-            si.afterPropertiesSet();
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertEquals("Unsupported configuration attributes: [ANOTHER_INVALID, INVALID_ATTRIBUTE]",
-                expected.getMessage());
-        }
+    @Test
+    public void runAsReplacementIsCorrectlySet() throws Exception {
+        SecurityContextHolder.getContext().setAuthentication(token);
+        token.setAuthenticated(true);
+        final RunAsManager runAs = jmock.mock(RunAsManager.class);
+        final RunAsUserToken runAsToken =
+            new RunAsUserToken("key", "someone", "creds", token.getAuthorities(), TestingAuthenticationToken.class);
+        interceptor.setRunAsManager(runAs);
+        jmock.checking(mdsWillReturnROLE_USERFromGetAttributes);
+        jmock.checking(new Expectations() {{
+            oneOf(runAs).buildRunAs(with(token), with(aNonNull(MethodInvocation.class)), with(aNonNull(List.class)));
+            will(returnValue(runAsToken));
+            ignoring(anything());
+        }});
+
+        String result = advisedTarget.makeUpperCase("hello");
+        assertEquals("HELLO org.springframework.security.runas.RunAsUserToken true", result);
+        // Check we've changed back
+        assertEquals(token, SecurityContextHolder.getContext().getAuthentication());
     }
 
-    public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-
-        assertTrue(si.isValidateConfigAttributes()); // check default
-        si.setValidateConfigAttributes(false);
-        assertTrue(!si.isValidateConfigAttributes()); // check changed
-
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(true, true));
-        si.afterPropertiesSet();
-        assertTrue(true);
+    @Test(expected=AuthenticationCredentialsNotFoundException.class)
+    public void emptySecurityContextIsRejected() throws Exception {
+        jmock.checking(new Expectations() {{
+            ignoring(anything());
+        }});
+        advisedTarget.makeUpperCase("hello");
     }
 
-    public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator()
-        throws Exception {
-        MethodSecurityInterceptor si = new MethodSecurityInterceptor();
-        si.setAccessDecisionManager(new MockAccessDecisionManager());
-        si.setRunAsManager(new MockRunAsManager());
-        si.setAuthenticationManager(new MockAuthenticationManager());
-
-        assertTrue(si.isValidateConfigAttributes()); // check default
-        si.setObjectDefinitionSource(new MockMethodDefinitionSource(true, false));
-        si.afterPropertiesSet();
-        assertTrue(true);
-    }
 
     //~ Inner Classes ==================================================================================================
 
+//    private static class MockMethodDefinitionSource() extends AbstractMethodDefinitionSource {
+//
+//    }
+
+    /*
     private class MockAccessDecisionManagerWhichOnlySupportsStrings implements AccessDecisionManager {
         public void decide(Authentication authentication, Object object, List<ConfigAttribute> configAttributes)
             throws AccessDeniedException {
@@ -477,5 +396,5 @@ public class MethodSecurityInterceptorTests extends TestCase {
         public boolean supports(ConfigAttribute attribute) {
             return true;
         }
-    }
+    }*/
 }

+ 0 - 56
core/src/test/resources/org/springframework/security/intercept/method/aopalliance/applicationContext.xml

@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
-<!--
- * Copyright 2004 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * $Id$
--->
-
-<beans>
-
-	<bean id="afterInvocation" class="org.springframework.security.MockAfterInvocationManager"/>
-	<bean id="authentication" class="org.springframework.security.MockAuthenticationManager"/>
-	<bean id="accessDecision" class="org.springframework.security.MockAccessDecisionManager"/>
-	<bean id="runAs" class="org.springframework.security.MockRunAsManager"/>
-
-   <bean id="secureObjectLoggerListener" class="org.springframework.security.event.authorization.LoggerListener"/>
-
-	<bean id="securityInterceptor" class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor">
-		<property name="authenticationManager"><ref local="authentication"/></property>
-		<property name="accessDecisionManager"><ref local="accessDecision"/></property>
-		<property name="afterInvocationManager"><ref local="afterInvocation"/></property>
-		<property name="runAsManager"><ref local="runAs"/></property>
-		<property name="objectDefinitionSource">
-			<value>
-                org.springframework.security.ITargetObject.makeLower*=MOCK_LOWER
-                org.springframework.security.ITargetObject.makeUpper*=MOCK_UPPER,RUN_AS
-                org.springframework.security.ITargetObject.computeHashCode*=MOCK_HASH,AFTER_INVOCATION_MOCK
-            </value>
-		</property>
-	</bean>
-
-	<bean id="realTarget" class="org.springframework.security.TargetObject"/>
-
-    <bean id="target" class="org.springframework.aop.framework.ProxyFactoryBean">
-      <property name="proxyInterfaces"><value>org.springframework.security.ITargetObject</value></property>
-      <property name="interceptorNames">
-         <list>
-            <idref local="securityInterceptor"/>
-            <idref local="realTarget"/>
-         </list>
-      </property>
-    </bean>
-
-</beans>