Converted MethodSecurityInterceptorTests to use mocks and deleted app context file.

This commit is contained in:
Luke Taylor 2008-11-30 23:20:16 +00:00
parent bfd4bcfdb7
commit a318aacc4f
3 changed files with 240 additions and 376 deletions

View File

@ -24,9 +24,8 @@ import java.io.Serializable;
* <p>
* When an {@link org.springframework.security.intercept.AbstractSecurityInterceptor}
* 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.
* 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).

View File

@ -15,35 +15,45 @@
package org.springframework.security.intercept.method.aopalliance;
import java.lang.reflect.Method;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import junit.framework.TestCase;
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 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;
public MethodSecurityInterceptorTests() {
super();
}
public MethodSecurityInterceptorTests(String arg0) {
super(arg0);
}
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")));
}};
}
@After
public void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
protected void tearDown() throws Exception {
super.tearDown();
SecurityContextHolder.clearContext();
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 makeInterceptedTarget() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
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 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(expected=IllegalArgumentException.class)
public void missingAccessDecisionManagerIsDetected() throws Exception {
interceptor.setAccessDecisionManager(null);
interceptor.afterPropertiesSet();
}
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 missingAuthenticationManagerIsDetected() throws Exception {
interceptor.setAuthenticationManager(null);
interceptor.afterPropertiesSet();
}
public void testCallingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts()
throws Exception {
ITargetObject target = makeInterceptedTarget();
String result = target.publicMakeLowerCase("HELLO");
@Test(expected=IllegalArgumentException.class)
public void missingMethodDefinitionSourceIsRejected() throws Exception {
interceptor.setObjectDefinitionSource(null);
interceptor.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void missingRunAsManagerIsRejected() throws Exception {
interceptor.setRunAsManager(null);
interceptor.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void initializationRejectsObjectDefinitionSourceThatDoesNotSupportMethodInvocation() throws Throwable {
jmock.checking(new Expectations() {{
oneOf(mds).supports(MethodInvocation.class); will(returnValue(false));
}});
interceptor.afterPropertiesSet();
}
@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();
}
@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();
}
@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();
}
@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();
}
@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();
}
@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();
}
@Test
public void callingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts() {
jmock.checking(mdsWillReturnNullFromGetAttributes);
String result = advisedTarget.publicMakeLowerCase("HELLO");
assertEquals("hello Authentication empty", result);
jmock.assertIsSatisfied();
}
public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillNotChangeItsIsAuthenticatedProperty()
throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password");
@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());
}
@Test(expected=AuthenticationException.class)
public void callIsWhenAuthenticationManagerRejectsAuthentication() throws Exception {
final TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password");
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);
jmock.checking(mdsWillReturnROLE_USERFromGetAttributes);
jmock.checking(new Expectations() {{
oneOf(authman).authenticate(token); will(throwException(new BadCredentialsException("rejected")));
}});
advisedTarget.makeLowerCase("HELLO");
}
public void testDeniesWhenAppropriate() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_NO_BENEFIT_TO_THIS_GRANTED_AUTHORITY")});
@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)));
}});
ITargetObject target = makeInterceptedTarget();
try {
target.makeUpperCase("HELLO");
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
}
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());
}
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);
}
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");
String result = advisedTarget.makeLowerCase("HELLO");
// Note we check the isAuthenticated remained true in following line
assertEquals("hello org.springframework.security.providers.UsernamePasswordAuthenticationToken true", result);
assertEquals("hello org.springframework.security.providers.TestingAuthenticationToken true", result);
}
public void testRejectionOfEmptySecurityContext() throws Exception {
ITargetObject target = makeInterceptedTarget();
try {
target.makeUpperCase("hello");
fail("Should have thrown AuthenticationCredentialsNotFoundException");
} catch (AuthenticationCredentialsNotFoundException expected) {
assertTrue(true);
}
}
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());
}
}
public void testRejectsCallsWhenAuthenticationIsIncorrect()
throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password");
assertTrue(!token.isAuthenticated());
@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")));
}});
// 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);
}
advisedTarget.makeUpperCase("HELLO");
}
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());
}
}
public void testRejectsCallsWhenObjectIsNull() throws Throwable {
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
try {
@Test(expected=IllegalArgumentException.class)
public void rejectsNullSecuredObjects() throws Throwable {
interceptor.invoke(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("Object was null", expected.getMessage());
}
}
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());
@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());
}});
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());
}
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 testStartupCheckForAccessDecisionManager()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setAfterInvocationManager(new MockAfterInvocationManager());
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
try {
si.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("An AccessDecisionManager is required", expected.getMessage());
}
@Test(expected=AuthenticationCredentialsNotFoundException.class)
public void emptySecurityContextIsRejected() throws Exception {
jmock.checking(new Expectations() {{
ignoring(anything());
}});
advisedTarget.makeUpperCase("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));
try {
si.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("An AuthenticationManager is required", expected.getMessage());
}
}
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());
}
}
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());
}
}
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:"));
}
}
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());
}
}
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);
}
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;
}
}
}*/
}

View File

@ -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>