mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-26 13:53:14 +00:00
SEC-1768: Added tests to reproduce "double-proxying" issue combining intercept-methods and tx-annotation-driven. Problem is caused by use of ProxyFactoryBean with auto-proxying.
This commit is contained in:
parent
b0a60a7ff2
commit
5a1ddc660b
@ -1,9 +1,5 @@
|
|||||||
package org.springframework.security.config.method;
|
package org.springframework.security.config.method;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
|
import org.springframework.aop.config.AbstractInterceptorDrivenBeanDefinitionDecorator;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
@ -13,7 +9,6 @@ import org.springframework.beans.factory.support.ManagedMap;
|
|||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.security.access.ConfigAttribute;
|
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
|
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
|
||||||
import org.springframework.security.access.method.MapBasedMethodSecurityMetadataSource;
|
import org.springframework.security.access.method.MapBasedMethodSecurityMetadataSource;
|
||||||
@ -24,6 +19,8 @@ import org.springframework.util.xml.DomUtils;
|
|||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.springframework.security.config;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
|
import org.springframework.transaction.TransactionException;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Luke Taylor
|
||||||
|
*/
|
||||||
|
public class MockTransactionManager implements PlatformTransactionManager {
|
||||||
|
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
|
||||||
|
return mock(TransactionStatus.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commit(TransactionStatus status) throws TransactionException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rollback(TransactionStatus status) throws TransactionException {
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package org.springframework.security.config;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.security.core.session.SessionCreationEvent;
|
import org.springframework.security.core.session.SessionCreationEvent;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.springframework.security.config;
|
||||||
|
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Luke Taylor
|
||||||
|
*/
|
||||||
|
public class TransactionalTestBusinessBean implements TestBusinessBean {
|
||||||
|
public void setInteger(int i) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInteger() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setString(String s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void doSomething() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unprotected() {
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,14 @@ package org.springframework.security.config.method;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.*;
|
||||||
import org.junit.Before;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.Test;
|
import org.springframework.aop.framework.Advised;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
@ -13,29 +18,34 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
|
|||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
||||||
import org.springframework.security.config.TestBusinessBean;
|
import org.springframework.security.config.TestBusinessBean;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
*/
|
*/
|
||||||
public class InterceptMethodsBeanDefinitionDecoratorTests {
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
private ClassPathXmlApplicationContext appContext;
|
@ContextConfiguration(locations = "classpath:org/springframework/security/config/method-security.xml")
|
||||||
|
public class InterceptMethodsBeanDefinitionDecoratorTests implements ApplicationContextAware {
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("target")
|
||||||
private TestBusinessBean target;
|
private TestBusinessBean target;
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("transactionalTarget")
|
||||||
|
private TestBusinessBean transactionalTarget;
|
||||||
|
private ApplicationContext appContext;
|
||||||
|
|
||||||
@Before
|
@BeforeClass
|
||||||
public void loadContext() {
|
public static void loadContext() {
|
||||||
// Set value for placeholder
|
// Set value for placeholder
|
||||||
System.setProperty("admin.role", "ROLE_ADMIN");
|
System.setProperty("admin.role", "ROLE_ADMIN");
|
||||||
appContext = new ClassPathXmlApplicationContext("org/springframework/security/config/method-security.xml");
|
|
||||||
target = (TestBusinessBean) appContext.getBean("target");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void closeAppContext() {
|
public void clearContext() {
|
||||||
if (appContext != null) {
|
|
||||||
appContext.close();
|
|
||||||
}
|
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +84,15 @@ public class InterceptMethodsBeanDefinitionDecoratorTests {
|
|||||||
SecurityContextHolder.getContext().setAuthentication(token);
|
SecurityContextHolder.getContext().setAuthentication(token);
|
||||||
|
|
||||||
target.doSomething();
|
target.doSomething();
|
||||||
fail("Expected AccessDeniedException");
|
}
|
||||||
|
|
||||||
|
@Test(expected = AuthenticationException.class)
|
||||||
|
public void transactionalMethodsShouldBeSecured() throws Exception {
|
||||||
|
transactionalTarget.doSomething();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.appContext = applicationContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,24 @@
|
|||||||
<b:beans xmlns="http://www.springframework.org/schema/security"
|
<b:beans xmlns="http://www.springframework.org/schema/security"
|
||||||
xmlns:b="http://www.springframework.org/schema/beans"
|
xmlns:b="http://www.springframework.org/schema/beans"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
|
||||||
|
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
||||||
|
|
||||||
|
<tx:annotation-driven />
|
||||||
|
|
||||||
|
<b:bean name="transactionManager" class="org.springframework.security.config.MockTransactionManager" />
|
||||||
|
|
||||||
<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>
|
<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>
|
||||||
|
|
||||||
|
<b:bean id="transactionalTarget" class="org.springframework.security.config.TransactionalTestBusinessBean">
|
||||||
|
<intercept-methods>
|
||||||
|
<protect method="*" access="ROLE_USER" />
|
||||||
|
</intercept-methods>
|
||||||
|
</b:bean>
|
||||||
|
|
||||||
|
|
||||||
<b:bean id="target" class="org.springframework.security.config.TestBusinessBeanImpl">
|
<b:bean id="target" class="org.springframework.security.config.TestBusinessBeanImpl">
|
||||||
<!-- This will add a security interceptor to the bean -->
|
<!-- This will add a security interceptor to the bean -->
|
||||||
<intercept-methods>
|
<intercept-methods>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user