mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-28 06:42:49 +00:00
Converted MethodSecurityInterceptorTests to use mocks and deleted app context file.
This commit is contained in:
parent
bfd4bcfdb7
commit
a318aacc4f
@ -24,9 +24,8 @@ import java.io.Serializable;
|
|||||||
* <p>
|
* <p>
|
||||||
* When an {@link org.springframework.security.intercept.AbstractSecurityInterceptor}
|
* When an {@link org.springframework.security.intercept.AbstractSecurityInterceptor}
|
||||||
* is set up, a list of configuration attributes is defined for secure object
|
* is set up, a list of configuration attributes is defined for secure object
|
||||||
* patterns. These configuration attributes have special meaning to a {@link
|
* patterns. These configuration attributes have special meaning to a {@link RunAsManager},
|
||||||
* RunAsManager}, {@link AccessDecisionManager} or
|
* {@link AccessDecisionManager} or <code>AccessDecisionManager</code> delegate.
|
||||||
* <code>AccessDecisionManager</code> delegate.
|
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Stored at runtime with other <code>ConfigAttribute</code>s for the same secure object target.
|
* 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
|
* 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
|
* <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
|
* 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
|
* return such a <code>String</code>.
|
||||||
* sufficient precision as a <code>String</code>, <code>null</code> should be returned. Returning
|
* <p>
|
||||||
* <code>null</code> will require any relying classes to specifically support the <code>ConfigAttribute</code>
|
* If the <code>ConfigAttribute</code> cannot be expressed with sufficient precision as a <code>String</code>,
|
||||||
* implementation, so returning <code>null</code> should be avoided unless actually required.</p>
|
* <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
|
* @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).
|
* cannot be expressed as a <code>String</code> with sufficient precision).
|
||||||
|
@ -15,35 +15,45 @@
|
|||||||
|
|
||||||
package org.springframework.security.intercept.method.aopalliance;
|
package org.springframework.security.intercept.method.aopalliance;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import static org.junit.Assert.assertEquals;
|
||||||
import java.util.Collection;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
import org.jmock.Expectations;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.jmock.Mockery;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
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.AccessDecisionManager;
|
||||||
import org.springframework.security.AccessDeniedException;
|
import org.springframework.security.AccessDeniedException;
|
||||||
import org.springframework.security.AfterInvocationManager;
|
import org.springframework.security.AfterInvocationManager;
|
||||||
import org.springframework.security.Authentication;
|
import org.springframework.security.Authentication;
|
||||||
import org.springframework.security.AuthenticationCredentialsNotFoundException;
|
import org.springframework.security.AuthenticationCredentialsNotFoundException;
|
||||||
import org.springframework.security.AuthenticationException;
|
import org.springframework.security.AuthenticationException;
|
||||||
|
import org.springframework.security.AuthenticationManager;
|
||||||
|
import org.springframework.security.BadCredentialsException;
|
||||||
import org.springframework.security.ConfigAttribute;
|
import org.springframework.security.ConfigAttribute;
|
||||||
import org.springframework.security.GrantedAuthority;
|
import org.springframework.security.GrantedAuthority;
|
||||||
import org.springframework.security.GrantedAuthorityImpl;
|
import org.springframework.security.GrantedAuthorityImpl;
|
||||||
import org.springframework.security.ITargetObject;
|
import org.springframework.security.ITargetObject;
|
||||||
import org.springframework.security.MockAccessDecisionManager;
|
import org.springframework.security.MockAccessDecisionManager;
|
||||||
import org.springframework.security.MockAfterInvocationManager;
|
|
||||||
import org.springframework.security.MockAuthenticationManager;
|
import org.springframework.security.MockAuthenticationManager;
|
||||||
import org.springframework.security.MockRunAsManager;
|
import org.springframework.security.MockRunAsManager;
|
||||||
import org.springframework.security.RunAsManager;
|
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.context.SecurityContextHolder;
|
||||||
import org.springframework.security.intercept.method.MethodDefinitionSource;
|
import org.springframework.security.intercept.method.MethodDefinitionSource;
|
||||||
import org.springframework.security.intercept.method.MockMethodDefinitionSource;
|
import org.springframework.security.intercept.method.MockMethodDefinitionSource;
|
||||||
|
import org.springframework.security.providers.TestingAuthenticationToken;
|
||||||
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.runas.RunAsManagerImpl;
|
import org.springframework.security.runas.RunAsManagerImpl;
|
||||||
|
import org.springframework.security.runas.RunAsUserToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link MethodSecurityInterceptor}.
|
* Tests {@link MethodSecurityInterceptor}.
|
||||||
@ -51,356 +61,265 @@ import org.springframework.security.runas.RunAsManagerImpl;
|
|||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class MethodSecurityInterceptorTests extends TestCase {
|
public class MethodSecurityInterceptorTests {
|
||||||
//~ Constructors ===================================================================================================
|
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() {
|
private Expectations mdsWillReturnNullFromGetAttributes;
|
||||||
super();
|
private Expectations mdsWillReturnROLE_USERFromGetAttributes;
|
||||||
}
|
|
||||||
|
|
||||||
public MethodSecurityInterceptorTests(String arg0) {
|
|
||||||
super(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
|
@Before
|
||||||
public final void setUp() throws Exception {
|
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();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void tearDown() throws Exception {
|
private void createTarget(boolean useMock) {
|
||||||
super.tearDown();
|
realTarget = useMock ? jmock.mock(ITargetObject.class) : new TargetObject();
|
||||||
SecurityContextHolder.clearContext();
|
ProxyFactory pf = new ProxyFactory(realTarget);
|
||||||
|
pf.addAdvice(interceptor);
|
||||||
|
advisedTarget = (ITargetObject) pf.getProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ITargetObject makeInterceptedTarget() {
|
@Test
|
||||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
public void gettersReturnExpectedData() {
|
||||||
"org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
|
RunAsManager runAs = jmock.mock(RunAsManager.class);
|
||||||
|
AfterInvocationManager aim = jmock.mock(AfterInvocationManager.class);
|
||||||
return (ITargetObject) context.getBean("target");
|
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() {
|
@Test(expected=IllegalArgumentException.class)
|
||||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
public void missingAccessDecisionManagerIsDetected() throws Exception {
|
||||||
"org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
|
interceptor.setAccessDecisionManager(null);
|
||||||
|
interceptor.afterPropertiesSet();
|
||||||
MockAuthenticationManager authenticationManager = new MockAuthenticationManager(false);
|
|
||||||
MethodSecurityInterceptor si = (MethodSecurityInterceptor) context.getBean("securityInterceptor");
|
|
||||||
si.setAuthenticationManager(authenticationManager);
|
|
||||||
|
|
||||||
return (ITargetObject) context.getBean("target");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ITargetObject makeInterceptedTargetWithoutAnAfterInvocationManager() {
|
@Test(expected=IllegalArgumentException.class)
|
||||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
public void missingAuthenticationManagerIsDetected() throws Exception {
|
||||||
"org/springframework/security/intercept/method/aopalliance/applicationContext.xml");
|
interceptor.setAuthenticationManager(null);
|
||||||
|
interceptor.afterPropertiesSet();
|
||||||
MethodSecurityInterceptor si = (MethodSecurityInterceptor) context.getBean("securityInterceptor");
|
|
||||||
si.setAfterInvocationManager(null);
|
|
||||||
|
|
||||||
return (ITargetObject) context.getBean("target");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCallingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts()
|
@Test(expected=IllegalArgumentException.class)
|
||||||
throws Exception {
|
public void missingMethodDefinitionSourceIsRejected() throws Exception {
|
||||||
ITargetObject target = makeInterceptedTarget();
|
interceptor.setObjectDefinitionSource(null);
|
||||||
String result = target.publicMakeLowerCase("HELLO");
|
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);
|
assertEquals("hello Authentication empty", result);
|
||||||
|
jmock.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillNotChangeItsIsAuthenticatedProperty()
|
@Test
|
||||||
throws Exception {
|
public void callingAPublicMethodWhenPresentingAnAuthenticationObjectDoesntChangeItsAuthenticatedProperty() {
|
||||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password");
|
jmock.checking(mdsWillReturnNullFromGetAttributes);
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
|
assertEquals("hello org.springframework.security.providers.TestingAuthenticationToken false",
|
||||||
|
advisedTarget.publicMakeLowerCase("HELLO"));
|
||||||
assertTrue(!token.isAuthenticated());
|
assertTrue(!token.isAuthenticated());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=AuthenticationException.class)
|
||||||
|
public void callIsWhenAuthenticationManagerRejectsAuthentication() throws Exception {
|
||||||
|
final TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password");
|
||||||
SecurityContextHolder.getContext().setAuthentication(token);
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
|
|
||||||
// The associated MockAuthenticationManager WILL accept the above UsernamePasswordAuthenticationToken
|
jmock.checking(mdsWillReturnROLE_USERFromGetAttributes);
|
||||||
ITargetObject target = makeInterceptedTarget();
|
jmock.checking(new Expectations() {{
|
||||||
String result = target.publicMakeLowerCase("HELLO");
|
oneOf(authman).authenticate(token); will(throwException(new BadCredentialsException("rejected")));
|
||||||
assertEquals("hello org.springframework.security.providers.UsernamePasswordAuthenticationToken false", result);
|
}});
|
||||||
|
|
||||||
|
advisedTarget.makeLowerCase("HELLO");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeniesWhenAppropriate() throws Exception {
|
@Test
|
||||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
|
public void callSucceedsIfAccessDecisionManagerGrantsAccess() throws Exception {
|
||||||
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_NO_BENEFIT_TO_THIS_GRANTED_AUTHORITY")});
|
token.setAuthenticated(true);
|
||||||
SecurityContextHolder.getContext().setAuthentication(token);
|
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();
|
String result = advisedTarget.makeLowerCase("HELLO");
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
// Note we check the isAuthenticated remained true in following line
|
// 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 {
|
@Test(expected=AccessDeniedException.class)
|
||||||
ITargetObject target = makeInterceptedTarget();
|
public void callIsntMadeWhenAccessDecisionManagerRejectsAccess() throws Exception {
|
||||||
|
|
||||||
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());
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(token);
|
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
|
advisedTarget.makeUpperCase("HELLO");
|
||||||
ITargetObject target = makeInterceptedTargetRejectsAuthentication();
|
|
||||||
|
|
||||||
try {
|
|
||||||
target.makeLowerCase("HELLO");
|
|
||||||
fail("Should have thrown AuthenticationException");
|
|
||||||
} catch (AuthenticationException expected) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
|
@Test(expected=IllegalArgumentException.class)
|
||||||
throws Throwable {
|
public void rejectsNullSecuredObjects() 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 {
|
|
||||||
interceptor.invoke(null);
|
interceptor.invoke(null);
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
assertEquals("Object was null", expected.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation()
|
@Test
|
||||||
throws Exception {
|
public void runAsReplacementIsCorrectlySet() throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
token.setAuthenticated(true);
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
final RunAsManager runAs = jmock.mock(RunAsManager.class);
|
||||||
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
|
final RunAsUserToken runAsToken =
|
||||||
si.setRunAsManager(new MockRunAsManagerWhichOnlySupportsStrings());
|
new RunAsUserToken("key", "someone", "creds", token.getAuthorities(), TestingAuthenticationToken.class);
|
||||||
si.setAfterInvocationManager(new MockAfterInvocationManager());
|
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 {
|
String result = advisedTarget.makeUpperCase("hello");
|
||||||
si.afterPropertiesSet();
|
assertEquals("HELLO org.springframework.security.runas.RunAsUserToken true", result);
|
||||||
fail("Should have thrown IllegalArgumentException");
|
// Check we've changed back
|
||||||
} catch (IllegalArgumentException expected) {
|
assertEquals(token, SecurityContextHolder.getContext().getAuthentication());
|
||||||
assertEquals("RunAsManager does not support secure object class: interface org.aopalliance.intercept.MethodInvocation",
|
|
||||||
expected.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartupCheckForAccessDecisionManager()
|
@Test(expected=AuthenticationCredentialsNotFoundException.class)
|
||||||
throws Exception {
|
public void emptySecurityContextIsRejected() throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
jmock.checking(new Expectations() {{
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
ignoring(anything());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
}});
|
||||||
si.setAfterInvocationManager(new MockAfterInvocationManager());
|
advisedTarget.makeUpperCase("hello");
|
||||||
|
|
||||||
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
|
|
||||||
|
|
||||||
try {
|
|
||||||
si.afterPropertiesSet();
|
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
assertEquals("An AccessDecisionManager is required", expected.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ==================================================================================================
|
//~ Inner Classes ==================================================================================================
|
||||||
|
|
||||||
|
// private static class MockMethodDefinitionSource() extends AbstractMethodDefinitionSource {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
private class MockAccessDecisionManagerWhichOnlySupportsStrings implements AccessDecisionManager {
|
private class MockAccessDecisionManagerWhichOnlySupportsStrings implements AccessDecisionManager {
|
||||||
public void decide(Authentication authentication, Object object, List<ConfigAttribute> configAttributes)
|
public void decide(Authentication authentication, Object object, List<ConfigAttribute> configAttributes)
|
||||||
throws AccessDeniedException {
|
throws AccessDeniedException {
|
||||||
@ -477,5 +396,5 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public boolean supports(ConfigAttribute attribute) {
|
public boolean supports(ConfigAttribute attribute) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -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>
|
|
Loading…
x
Reference in New Issue
Block a user