+ interaction with user code uses now dedicated privileged when running under a security manager
This commit is contained in:
parent
fe5b5022f0
commit
d5d3104b7b
|
|
@ -22,6 +22,10 @@ import java.lang.reflect.Array;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
|
@ -31,7 +35,6 @@ import java.util.Set;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -102,6 +105,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
*/
|
||||
private Map<String, BeanWrapperImpl> nestedBeanWrappers;
|
||||
|
||||
/** The security context used for invoking the property methods */
|
||||
private AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
|
||||
|
|
@ -198,6 +204,16 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
setIntrospectionClass(object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security context used during the invocation of the wrapped instance methods.
|
||||
* Can be null.
|
||||
*
|
||||
* @param acc
|
||||
*/
|
||||
public void setSecurityContext(AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
public final Object getWrappedInstance() {
|
||||
return this.object;
|
||||
}
|
||||
|
|
@ -539,12 +555,29 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
if (pd == null || pd.getReadMethod() == null) {
|
||||
throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
|
||||
}
|
||||
Method readMethod = pd.getReadMethod();
|
||||
final Method readMethod = pd.getReadMethod();
|
||||
try {
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
||||
readMethod.setAccessible(true);
|
||||
}
|
||||
Object value = readMethod.invoke(this.object, (Object[]) null);
|
||||
|
||||
Object value = null;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
value = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
return readMethod.invoke(object, (Object[]) null);
|
||||
}
|
||||
},acc);
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = readMethod.invoke(object, (Object[]) null);
|
||||
}
|
||||
|
||||
if (tokens.keys != null) {
|
||||
// apply indexes and map keys
|
||||
for (int i = 0; i < tokens.keys.length; i++) {
|
||||
|
|
@ -602,7 +635,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Getter for property '" + actualName + "' threw exception", ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
|
||||
catch(IllegalAccessException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Illegal attempt to get property '" + actualName + "' threw exception", ex);
|
||||
}
|
||||
|
|
@ -614,6 +648,10 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Invalid index in property path '" + propertyName + "'", ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Invalid index in property path '" + propertyName + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -813,14 +851,26 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
}
|
||||
else {
|
||||
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
|
||||
Method readMethod = pd.getReadMethod();
|
||||
final Method readMethod = pd.getReadMethod();
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
||||
readMethod.setAccessible(true);
|
||||
}
|
||||
try {
|
||||
oldValue = readMethod.invoke(this.object);
|
||||
if (System.getSecurityManager() != null) {
|
||||
oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
return readMethod.invoke(object);
|
||||
}
|
||||
},acc);
|
||||
}
|
||||
else {
|
||||
oldValue = readMethod.invoke(object);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (ex instanceof PrivilegedActionException) {
|
||||
ex = ((PrivilegedActionException) ex).getException();
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not read previous value of property '" +
|
||||
this.nestedPath + propertyName + "'", ex);
|
||||
|
|
@ -831,11 +881,28 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
}
|
||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||
}
|
||||
Method writeMethod = pd.getWriteMethod();
|
||||
final Method writeMethod = pd.getWriteMethod();
|
||||
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
|
||||
writeMethod.setAccessible(true);
|
||||
}
|
||||
writeMethod.invoke(this.object, valueToApply);
|
||||
final Object value = valueToApply;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
writeMethod.invoke(object, value);
|
||||
return null;
|
||||
}
|
||||
},acc);
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw ex.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeMethod.invoke(object, value);
|
||||
}
|
||||
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
PropertyChangeEvent propertyChangeEvent =
|
||||
|
|
@ -862,6 +929,11 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new MethodInvocationException(pce, ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new MethodInvocationException(pce, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import java.lang.reflect.Modifier;
|
|||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -330,13 +332,27 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
|
||||
public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
|
||||
final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
|
||||
return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
|
||||
}
|
||||
else {
|
||||
Object bean = getInstantiationStrategy().instantiate(bd, null, this);
|
||||
Object bean = null;
|
||||
final BeanFactory parent = this;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
bean = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
return getInstantiationStrategy().instantiate(bd, null, parent);
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
bean = getInstantiationStrategy().instantiate(bd, null, parent);
|
||||
}
|
||||
|
||||
populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
|
||||
return bean;
|
||||
}
|
||||
|
|
@ -403,9 +419,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
|
||||
throws BeanCreationException {
|
||||
|
||||
AccessControlContext acc = AccessController.getContext();
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
|
|
@ -438,8 +451,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
logger.debug("Finished creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
return beanInstance;
|
||||
}
|
||||
}, acc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -904,9 +915,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* @param mbd the bean definition for the bean
|
||||
* @return BeanWrapper for the new instance
|
||||
*/
|
||||
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
|
||||
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
|
||||
try {
|
||||
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
|
||||
Object beanInstance = null;
|
||||
final BeanFactory parent = this;
|
||||
if (System.getSecurityManager() != null) {
|
||||
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
|
||||
}
|
||||
|
||||
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
|
||||
initBeanWrapper(bw);
|
||||
return bw;
|
||||
|
|
@ -1229,6 +1253,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
|
||||
MutablePropertyValues mpvs = null;
|
||||
List<PropertyValue> original;
|
||||
|
||||
if (System.getSecurityManager()!= null) {
|
||||
if (bw instanceof BeanWrapperImpl) {
|
||||
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
|
||||
}
|
||||
}
|
||||
|
||||
if (pvs instanceof MutablePropertyValues) {
|
||||
mpvs = (MutablePropertyValues) pvs;
|
||||
|
|
@ -1337,19 +1367,20 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* @see #invokeInitMethods
|
||||
* @see #applyBeanPostProcessorsAfterInitialization
|
||||
*/
|
||||
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
|
||||
if (bean instanceof BeanNameAware) {
|
||||
((BeanNameAware) bean).setBeanName(beanName);
|
||||
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
return null;
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
|
||||
if (bean instanceof BeanClassLoaderAware) {
|
||||
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
|
||||
else {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
}
|
||||
|
||||
if (bean instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) bean).setBeanFactory(this);
|
||||
}
|
||||
|
||||
|
||||
Object wrappedBean = bean;
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
|
||||
|
|
@ -1369,6 +1400,20 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
}
|
||||
return wrappedBean;
|
||||
}
|
||||
|
||||
private void invokeAwareMethods(final String beanName, final Object bean) {
|
||||
if (bean instanceof BeanNameAware) {
|
||||
((BeanNameAware) bean).setBeanName(beanName);
|
||||
}
|
||||
|
||||
if (bean instanceof BeanClassLoaderAware) {
|
||||
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
|
||||
}
|
||||
|
||||
if (bean instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Give a bean a chance to react now all its properties are set,
|
||||
|
|
@ -1382,7 +1427,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* @throws Throwable if thrown by init methods or by the invocation process
|
||||
* @see #invokeCustomInitMethod
|
||||
*/
|
||||
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
|
||||
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
|
||||
throws Throwable {
|
||||
|
||||
boolean isInitializingBean = (bean instanceof InitializingBean);
|
||||
|
|
@ -1390,7 +1435,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
|
||||
}
|
||||
((InitializingBean) bean).afterPropertiesSet();
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
((InitializingBean) bean).afterPropertiesSet();
|
||||
return null;
|
||||
}
|
||||
},getAccessControlContext());
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
((InitializingBean) bean).afterPropertiesSet();
|
||||
}
|
||||
}
|
||||
|
||||
if (mbd != null) {
|
||||
|
|
@ -1413,9 +1473,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* @param enforceInitMethod indicates whether the defined init method needs to exist
|
||||
* @see #invokeInitMethods
|
||||
*/
|
||||
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable {
|
||||
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
|
||||
String initMethodName = mbd.getInitMethodName();
|
||||
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
|
||||
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
|
||||
BeanUtils.findMethod(bean.getClass(), initMethodName) :
|
||||
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
|
||||
if (initMethod == null) {
|
||||
|
|
@ -1437,11 +1497,23 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
ReflectionUtils.makeAccessible(initMethod);
|
||||
try {
|
||||
initMethod.invoke(bean, (Object[]) null);
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
|
||||
public Object run() throws Exception {
|
||||
initMethod.invoke(bean, (Object[]) null);
|
||||
return null;
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
InvocationTargetException ex = (InvocationTargetException) pae.getException();
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
else {
|
||||
initMethod.invoke(bean, (Object[]) null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
|
@ -151,6 +156,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
|
||||
new NamedThreadLocal<Object>("Prototype beans currently in creation");
|
||||
|
||||
/** security context used when running with a Security Manager */
|
||||
private volatile SecurityContextProvider securityProvider = new SimpleSecurityContextProvider();
|
||||
|
||||
/**
|
||||
* Create a new AbstractBeanFactory.
|
||||
*/
|
||||
|
|
@ -196,6 +204,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
return doGetBean(name, requiredType, args, false);
|
||||
}
|
||||
|
||||
protected <T> T doGetBean(
|
||||
final String name, final Class<T> requiredType, final Object[] args, final boolean typeCheckOnly)
|
||||
throws BeansException {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<T>() {
|
||||
|
||||
public T run() {
|
||||
return doGetBeanRaw(name, requiredType, args, typeCheckOnly);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Return an instance, which may be shared or independent, of the specified bean.
|
||||
* @param name the name of the bean to retrieve
|
||||
|
|
@ -208,7 +226,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T doGetBean(
|
||||
private <T> T doGetBeanRaw(
|
||||
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
|
||||
throws BeansException {
|
||||
|
||||
|
|
@ -409,9 +427,19 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
return false;
|
||||
}
|
||||
if (isFactoryBean(beanName, mbd)) {
|
||||
FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean) factoryBean).isPrototype()) ||
|
||||
!factoryBean.isSingleton());
|
||||
final FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return Boolean.valueOf(((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean) factoryBean).isPrototype()) ||
|
||||
!factoryBean.isSingleton()));
|
||||
}
|
||||
}, getAccessControlContext()).booleanValue();
|
||||
}
|
||||
else {
|
||||
return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean) factoryBean).isPrototype()) ||
|
||||
!factoryBean.isSingleton());
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
|
@ -861,7 +889,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* @param mbd the merged bean definition
|
||||
*/
|
||||
protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) {
|
||||
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors()).destroy();
|
||||
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
|
||||
}
|
||||
|
||||
public void destroyScopedBean(String beanName) {
|
||||
|
|
@ -1136,34 +1164,54 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* @return the resolved bean class (or <code>null</code> if none)
|
||||
* @throws CannotLoadBeanClassException if we failed to load the class
|
||||
*/
|
||||
protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName, Class[] typesToMatch)
|
||||
protected Class resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class[] typesToMatch)
|
||||
throws CannotLoadBeanClassException {
|
||||
try {
|
||||
if (mbd.hasBeanClass()) {
|
||||
return mbd.getBeanClass();
|
||||
}
|
||||
if (typesToMatch != null) {
|
||||
ClassLoader tempClassLoader = getTempClassLoader();
|
||||
if (tempClassLoader != null) {
|
||||
if (tempClassLoader instanceof DecoratingClassLoader) {
|
||||
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
|
||||
for (Class typeToMatch : typesToMatch) {
|
||||
dcl.excludeClass(typeToMatch.getName());
|
||||
}
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(new PrivilegedExceptionAction<Class>() {
|
||||
|
||||
public Class run() throws Exception {
|
||||
return doResolveBeanClass(mbd, typesToMatch);
|
||||
}
|
||||
String className = mbd.getBeanClassName();
|
||||
return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
return mbd.resolveBeanClass(getBeanClassLoader());
|
||||
else {
|
||||
return doResolveBeanClass(mbd, typesToMatch);
|
||||
}
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), (ClassNotFoundException) ex);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), (ClassNotFoundException) ex);
|
||||
}
|
||||
catch (LinkageError err) {
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
|
||||
}
|
||||
}
|
||||
|
||||
private Class doResolveBeanClass(final RootBeanDefinition mbd, final Class[] typesToMatch)
|
||||
throws ClassNotFoundException {
|
||||
if (typesToMatch != null) {
|
||||
ClassLoader tempClassLoader = getTempClassLoader();
|
||||
if (tempClassLoader != null) {
|
||||
if (tempClassLoader instanceof DecoratingClassLoader) {
|
||||
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
|
||||
for (Class<?> typeToMatch : typesToMatch) {
|
||||
dcl.excludeClass(typeToMatch.getName());
|
||||
}
|
||||
}
|
||||
String className = mbd.getBeanClassName();
|
||||
return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
|
||||
}
|
||||
}
|
||||
return mbd.resolveBeanClass(getBeanClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the given String as contained in a bean definition,
|
||||
|
|
@ -1363,13 +1411,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* @see #registerDependentBean
|
||||
*/
|
||||
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
|
||||
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
|
||||
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
|
||||
if (mbd.isSingleton()) {
|
||||
// Register a DisposableBean implementation that performs all destruction
|
||||
// work for the given bean: DestructionAwareBeanPostProcessors,
|
||||
// DisposableBean interface, custom destroy method.
|
||||
registerDisposableBean(beanName,
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors()));
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
|
||||
}
|
||||
else {
|
||||
// A bean with a custom scope...
|
||||
|
|
@ -1378,11 +1427,41 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
|
||||
}
|
||||
scope.registerDestructionCallback(beanName,
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors()));
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Delegate the creation of the security context to {@link #getSecurityContextProvider()}.
|
||||
*/
|
||||
@Override
|
||||
protected AccessControlContext getAccessControlContext() {
|
||||
SecurityContextProvider provider = getSecurityContextProvider();
|
||||
return (provider != null ? provider.getAccessControlContext(): null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the security context provider for this bean factory.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SecurityContextProvider getSecurityContextProvider() {
|
||||
return securityProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security context provider for this bean factory. If a security manager
|
||||
* is set, interaction with the user code will be executed using the privileged
|
||||
* of the provided security context.
|
||||
*
|
||||
* @param securityProvider
|
||||
*/
|
||||
public void setSecurityContextProvider(SecurityContextProvider securityProvider) {
|
||||
this.securityProvider = securityProvider;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Abstract methods to be implemented by subclasses
|
||||
|
|
@ -1442,5 +1521,4 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
*/
|
||||
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
|
||||
throws BeanCreationException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -99,7 +102,7 @@ class ConstructorResolver {
|
|||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
public BeanWrapper autowireConstructor(
|
||||
String beanName, RootBeanDefinition mbd, Constructor[] chosenCtors, Object[] explicitArgs) {
|
||||
final String beanName, final RootBeanDefinition mbd, Constructor[] chosenCtors, final Object[] explicitArgs) {
|
||||
|
||||
BeanWrapperImpl bw = new BeanWrapperImpl();
|
||||
this.beanFactory.initBeanWrapper(bw);
|
||||
|
|
@ -256,8 +259,25 @@ class ConstructorResolver {
|
|||
}
|
||||
|
||||
try {
|
||||
Object beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
|
||||
Object beanInstance = null;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
final Constructor ctorToUse = constructorToUse;
|
||||
final Object[] argumentsToUse = argsToUse;
|
||||
|
||||
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
return beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
|
||||
}
|
||||
}, beanFactory.getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
beanInstance = beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, beanFactory, constructorToUse, argsToUse);
|
||||
}
|
||||
|
||||
bw.setWrappedInstance(beanInstance);
|
||||
return bw;
|
||||
}
|
||||
|
|
@ -311,7 +331,7 @@ class ConstructorResolver {
|
|||
* method, or <code>null</code> if none (-> use constructor argument values from bean definition)
|
||||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
|
||||
public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {
|
||||
BeanWrapperImpl bw = new BeanWrapperImpl();
|
||||
this.beanFactory.initBeanWrapper(bw);
|
||||
|
||||
|
|
@ -491,8 +511,27 @@ class ConstructorResolver {
|
|||
}
|
||||
|
||||
try {
|
||||
Object beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
|
||||
|
||||
Object beanInstance = null;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
final Object fb = factoryBean;
|
||||
final Method factoryMethod = factoryMethodToUse;
|
||||
final Object[] args = argsToUse;
|
||||
|
||||
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
return beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, beanFactory, fb, factoryMethod, args);
|
||||
}
|
||||
}, beanFactory.getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
beanInstance = beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, beanFactory, factoryBean, factoryMethodToUse, argsToUse);
|
||||
}
|
||||
|
||||
if (beanInstance == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -808,5 +847,4 @@ class ConstructorResolver {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,8 @@ import java.io.Serializable;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -179,10 +181,21 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
* when deciding whether a bean definition should be considered as a
|
||||
* candidate for autowiring.
|
||||
*/
|
||||
public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {
|
||||
public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
|
||||
Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
|
||||
if (autowireCandidateResolver instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
|
||||
if (System.getSecurityManager() != null) {
|
||||
final BeanFactory target = this;
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(target);
|
||||
return null;
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
|
||||
}
|
||||
}
|
||||
this.autowireCandidateResolver = autowireCandidateResolver;
|
||||
}
|
||||
|
|
@ -493,8 +506,20 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
|
||||
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
|
||||
if (isFactoryBean(beanName)) {
|
||||
FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
if (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()) {
|
||||
final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
boolean isEagerInit = false;
|
||||
|
||||
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
|
||||
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return Boolean.valueOf(((SmartFactoryBean) factory).isEagerInit());
|
||||
}
|
||||
}, getAccessControlContext()).booleanValue();
|
||||
}
|
||||
else {
|
||||
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();
|
||||
}
|
||||
if (isEagerInit) {
|
||||
getBean(beanName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ package org.springframework.beans.factory.support;
|
|||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -66,6 +70,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
|
||||
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
||||
|
||||
private final AccessControlContext acc;
|
||||
|
||||
/**
|
||||
* Create a new DisposableBeanAdapter for the given bean.
|
||||
|
|
@ -76,7 +81,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
* (potentially DestructionAwareBeanPostProcessor), if any
|
||||
*/
|
||||
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
|
||||
List<BeanPostProcessor> postProcessors) {
|
||||
List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
|
||||
|
||||
Assert.notNull(bean, "Bean must not be null");
|
||||
this.bean = bean;
|
||||
|
|
@ -84,6 +89,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
this.invokeDisposableBean =
|
||||
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.acc = acc;
|
||||
|
||||
String destroyMethodName = beanDefinition.getDestroyMethodName();
|
||||
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
|
|
@ -131,6 +138,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
this.beanPostProcessors = postProcessors;
|
||||
this.acc = null;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -169,7 +177,18 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
((DisposableBean) this.bean).destroy();
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
|
||||
public Object run() throws Exception {
|
||||
((DisposableBean) bean).destroy();
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
}
|
||||
else {
|
||||
((DisposableBean) bean).destroy();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
|
||||
|
|
@ -199,9 +218,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
* for a method with a single boolean argument (passing in "true",
|
||||
* assuming a "force" parameter), else logging an error.
|
||||
*/
|
||||
private void invokeCustomDestroyMethod(Method destroyMethod) {
|
||||
private void invokeCustomDestroyMethod(final Method destroyMethod) {
|
||||
Class[] paramTypes = destroyMethod.getParameterTypes();
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
final Object[] args = new Object[paramTypes.length];
|
||||
if (paramTypes.length == 1) {
|
||||
args[0] = Boolean.TRUE;
|
||||
}
|
||||
|
|
@ -211,9 +230,22 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
}
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
try {
|
||||
destroyMethod.invoke(this.bean, args);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
destroyMethod.invoke(bean, args);
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
} catch (PrivilegedActionException pax) {
|
||||
throw (InvocationTargetException) pax.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
destroyMethod.invoke(bean, args);
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
String msg = "Invocation of destroy method '" + this.destroyMethodName +
|
||||
"' failed on bean with name '" + this.beanName + "'";
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.springframework.beans.factory.support;
|
|||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
|
@ -50,9 +52,18 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
|||
* @return the FactoryBean's object type,
|
||||
* or <code>null</code> if the type cannot be determined yet
|
||||
*/
|
||||
protected Class getTypeForFactoryBean(FactoryBean factoryBean) {
|
||||
protected Class getTypeForFactoryBean(final FactoryBean factoryBean) {
|
||||
try {
|
||||
return factoryBean.getObjectType();
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Class>() {
|
||||
public Class run() {
|
||||
return factoryBean.getObjectType();
|
||||
}
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return factoryBean.getObjectType();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// Thrown from the FactoryBean's getObjectType implementation.
|
||||
|
|
@ -112,40 +123,51 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
|||
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
|
||||
throws BeanCreationException {
|
||||
|
||||
AccessControlContext acc = AccessController.getContext();
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
Object object;
|
||||
|
||||
|
||||
|
||||
Object object;
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessControlContext acc = getAccessControlContext();
|
||||
try {
|
||||
object = factory.getObject();
|
||||
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
return factory.getObject();
|
||||
}
|
||||
}, acc);
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
catch (FactoryBeanNotInitializedException ex) {
|
||||
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
|
||||
}
|
||||
|
||||
// Do not accept a null value for a FactoryBean that's not fully
|
||||
// initialized yet: Many FactoryBeans just return null then.
|
||||
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
|
||||
throw new BeanCurrentlyInCreationException(
|
||||
beanName, "FactoryBean which is currently in creation returned null from getObject");
|
||||
}
|
||||
|
||||
if (object != null && shouldPostProcess) {
|
||||
try {
|
||||
object = postProcessObjectFromFactoryBean(object, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
}, acc);
|
||||
else {
|
||||
object = factory.getObject();
|
||||
}
|
||||
}
|
||||
catch (FactoryBeanNotInitializedException ex) {
|
||||
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
|
||||
}
|
||||
|
||||
|
||||
// Do not accept a null value for a FactoryBean that's not fully
|
||||
// initialized yet: Many FactoryBeans just return null then.
|
||||
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
|
||||
throw new BeanCurrentlyInCreationException(
|
||||
beanName, "FactoryBean which is currently in creation returned null from getObject");
|
||||
}
|
||||
|
||||
if (object != null && shouldPostProcess) {
|
||||
try {
|
||||
object = postProcessObjectFromFactoryBean(object, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -185,5 +207,15 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
|||
super.removeSingleton(beanName);
|
||||
this.factoryBeanObjectCache.remove(beanName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the security context for this bean factory. If a security manager
|
||||
* is set, interaction with the user code will be executed using the privileged
|
||||
* of the security context returned by this method.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected AccessControlContext getAccessControlContext() {
|
||||
return AccessController.getContext();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
/**
|
||||
* Provider of the security context of the code running inside the bean factory.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public interface SecurityContextProvider {
|
||||
|
||||
/**
|
||||
* Provides a security access control context relevant to a bean factory.
|
||||
*
|
||||
* @return bean factory security control context
|
||||
*/
|
||||
AccessControlContext getAccessControlContext();
|
||||
}
|
||||
|
|
@ -19,6 +19,9 @@ package org.springframework.beans.factory.support;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
|
@ -46,12 +49,17 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
|||
if (beanDefinition.getMethodOverrides().isEmpty()) {
|
||||
Constructor constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;
|
||||
if (constructorToUse == null) {
|
||||
Class clazz = beanDefinition.getBeanClass();
|
||||
final Class clazz = beanDefinition.getBeanClass();
|
||||
if (clazz.isInterface()) {
|
||||
throw new BeanInstantiationException(clazz, "Specified class is an interface");
|
||||
}
|
||||
try {
|
||||
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
|
||||
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
|
||||
|
||||
public Constructor run() throws Exception {
|
||||
return clazz.getDeclaredConstructor((Class[]) null);
|
||||
}
|
||||
});
|
||||
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
|
@ -107,11 +115,17 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
|||
|
||||
public Object instantiate(
|
||||
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
|
||||
Object factoryBean, Method factoryMethod, Object[] args) {
|
||||
Object factoryBean, final Method factoryMethod, Object[] args) {
|
||||
|
||||
try {
|
||||
// It's a static method if the target is null.
|
||||
ReflectionUtils.makeAccessible(factoryMethod);
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
ReflectionUtils.makeAccessible(factoryMethod);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return factoryMethod.invoke(factoryBean, args);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* Simple #SecurityContextProvider implementation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class SimpleSecurityContextProvider implements SecurityContextProvider {
|
||||
|
||||
private final AccessControlContext acc;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SimpleSecurityContextProvider</code> instance.
|
||||
*
|
||||
* The security context will be retrieved on each call from the current
|
||||
* thread.
|
||||
*/
|
||||
public SimpleSecurityContextProvider() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SimpleSecurityContextProvider</code> instance.
|
||||
*
|
||||
* If the given control context is null, the security context will be
|
||||
* retrieved on each call from the current thread.
|
||||
*
|
||||
* @see AccessController#getContext()
|
||||
* @param acc
|
||||
* access control context (can be null)
|
||||
*/
|
||||
public SimpleSecurityContextProvider(AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return (acc == null ? AccessController.getContext() : acc);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.PropertyPermission;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanFactory;
|
||||
import org.springframework.beans.factory.support.SecurityContextProvider;
|
||||
import org.springframework.beans.factory.support.security.support.ConstructorBean;
|
||||
import org.springframework.beans.factory.support.security.support.CustomCallbackBean;
|
||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CallbacksSecurityTest extends TestCase {
|
||||
|
||||
private XmlBeanFactory beanFactory;
|
||||
private SecurityContextProvider provider;
|
||||
|
||||
public CallbacksSecurityTest() {
|
||||
// setup security
|
||||
if (System.getSecurityManager() == null) {
|
||||
Policy policy = Policy.getPolicy();
|
||||
URL policyURL = getClass().getResource("/org/springframework/beans/factory/support/security/policy.all");
|
||||
System.setProperty("java.security.policy", policyURL.toString());
|
||||
System.setProperty("policy.allowSystemProperty", "true");
|
||||
policy.refresh();
|
||||
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
final ProtectionDomain empty = new ProtectionDomain(null, new Permissions());
|
||||
|
||||
provider = new SecurityContextProvider() {
|
||||
private final AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] { empty });
|
||||
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return acc;
|
||||
}
|
||||
};
|
||||
|
||||
DefaultResourceLoader drl = new DefaultResourceLoader();
|
||||
Resource config = drl.getResource("/org/springframework/beans/factory/support/security/callbacks.xml");
|
||||
beanFactory = new XmlBeanFactory(config);
|
||||
|
||||
beanFactory.setSecurityContextProvider(provider);
|
||||
}
|
||||
|
||||
public void testSecuritySanity() throws Exception {
|
||||
AccessControlContext acc = provider.getAccessControlContext();
|
||||
try {
|
||||
acc.checkPermission(new PropertyPermission("*", "read"));
|
||||
fail("Acc should not have any permissions");
|
||||
} catch (SecurityException se) {
|
||||
// expected
|
||||
}
|
||||
|
||||
final CustomCallbackBean bean = new CustomCallbackBean();
|
||||
final Method method = bean.getClass().getMethod("destroy", null);
|
||||
method.setAccessible(true);
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
|
||||
public Object run() throws Exception {
|
||||
method.invoke(bean, null);
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
fail("expected security exception");
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
final Class<ConstructorBean> cl = ConstructorBean.class;
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
|
||||
public Object run() throws Exception {
|
||||
return cl.newInstance();
|
||||
}
|
||||
}, acc);
|
||||
fail("expected security exception");
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSpringInitBean() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("spring-init");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getCause() instanceof SecurityException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCustomInitBean() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("custom-init");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getCause() instanceof SecurityException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSpringDestroyBean() throws Exception {
|
||||
beanFactory.getBean("spring-destroy");
|
||||
beanFactory.destroySingletons();
|
||||
assertNull(System.getProperty("security.destroy"));
|
||||
}
|
||||
|
||||
public void testCustomDestroyBean() throws Exception {
|
||||
beanFactory.getBean("custom-destroy");
|
||||
beanFactory.destroySingletons();
|
||||
assertNull(System.getProperty("security.destroy"));
|
||||
}
|
||||
|
||||
public void testCustomFactoryObject() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("spring-factory");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getCause() instanceof SecurityException);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testCustomFactoryType() throws Exception {
|
||||
assertNull(beanFactory.getType("spring-factory"));
|
||||
assertNull(System.getProperty("factory.object.type"));
|
||||
}
|
||||
|
||||
public void testCustomStaticFactoryMethod() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("custom-static-factory-method");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getMostSpecificCause() instanceof SecurityException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCustomInstanceFactoryMethod() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("custom-factory-method");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getMostSpecificCause() instanceof SecurityException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testTrustedFactoryMethod() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("trusted-factory-method");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getMostSpecificCause() instanceof SecurityException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testConstructor() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("constructor");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
// expected
|
||||
assertTrue(ex.getMostSpecificCause() instanceof SecurityException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testContainerPriviledges() throws Exception {
|
||||
AccessControlContext acc = provider.getAccessControlContext();
|
||||
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
|
||||
public Object run() throws Exception {
|
||||
beanFactory.getBean("working-factory-method");
|
||||
beanFactory.getBean("container-execution");
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
}
|
||||
|
||||
public void testPropertyInjection() throws Exception {
|
||||
try {
|
||||
beanFactory.getBean("property-injection");
|
||||
fail("expected security exception");
|
||||
} catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getMessage().contains("security"));
|
||||
}
|
||||
|
||||
beanFactory.getBean("working-property-injection");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
|
||||
default-lazy-init="true">
|
||||
|
||||
<bean name="spring-init" class="org.springframework.beans.factory.support.security.support.InitBean"/>
|
||||
|
||||
<bean name="spring-destroy" class="org.springframework.beans.factory.support.security.support.DestroyBean"/>
|
||||
|
||||
<bean name="custom-init" class="org.springframework.beans.factory.support.security.support.CustomCallbackBean"
|
||||
init-method="init"/>
|
||||
|
||||
<bean name="custom-destroy" class="org.springframework.beans.factory.support.security.support.CustomCallbackBean"
|
||||
destroy-method="destroy"/>
|
||||
|
||||
<bean name="spring-factory" class="org.springframework.beans.factory.support.security.support.CustomFactoryBean"/>
|
||||
|
||||
<bean name="custom-static-factory-method" class="org.springframework.beans.factory.support.security.support.FactoryBean" factory-method="makeStaticInstance"/>
|
||||
|
||||
<bean name="factory-bean" class="org.springframework.beans.factory.support.security.support.FactoryBean"/>
|
||||
|
||||
<bean name="custom-factory-method" factory-bean="factory-bean" factory-method="makeInstance"/>
|
||||
|
||||
<bean name="trusted-factory-method" class="java.lang.System" factory-method="getProperties"/>
|
||||
|
||||
<bean name="constructor" class="org.springframework.beans.factory.support.security.support.ConstructorBean"/>
|
||||
|
||||
<bean name="working-factory-method" class="org.springframework.beans.factory.support.security.support.FactoryBean" factory-method="protectedStaticInstance"/>
|
||||
|
||||
<bean name="container-execution" class="org.springframework.beans.factory.support.security.support.ConstructorBean">
|
||||
<constructor-arg ref="working-factory-method"/>
|
||||
</bean>
|
||||
|
||||
<bean name="property-injection" class="org.springframework.beans.factory.support.security.support.PropertyBean">
|
||||
<property name="securityProperty" value="value"/>
|
||||
</bean>
|
||||
|
||||
<bean name="working-property-injection" class="org.springframework.beans.factory.support.security.support.PropertyBean">
|
||||
<property name="property">
|
||||
<array>
|
||||
<ref bean="working-factory-method"/>
|
||||
</array>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
grant {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class ConstructorBean {
|
||||
|
||||
public ConstructorBean() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public ConstructorBean(Object obj) {
|
||||
System.out.println("Received object " + obj);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomCallbackBean {
|
||||
|
||||
public void init() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
public Class getObjectType() {
|
||||
System.setProperty("factory.object.type", "true");
|
||||
return Properties.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DestroyBean implements DisposableBean {
|
||||
|
||||
public void destroy() throws Exception {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class FactoryBean {
|
||||
|
||||
public static Object makeStaticInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
|
||||
protected static Object protectedStaticInstance() {
|
||||
return "protectedStaticInstance";
|
||||
}
|
||||
|
||||
public Object makeInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class InitBean implements InitializingBean {
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
System.getProperties();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class PropertyBean {
|
||||
|
||||
public void setSecurityProperty(Object property) {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void setProperty(Object property) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -16,11 +16,18 @@
|
|||
|
||||
package org.springframework.context.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.AbstractBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
|
||||
|
|
@ -56,7 +63,35 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
|
|||
}
|
||||
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
|
||||
AccessControlContext acc = null;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
if (applicationContext instanceof ConfigurableApplicationContext) {
|
||||
ConfigurableListableBeanFactory factory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
|
||||
if (factory instanceof AbstractBeanFactory) {
|
||||
acc = ((AbstractBeanFactory) factory).getSecurityContextProvider().getAccessControlContext();
|
||||
}
|
||||
}
|
||||
// optimize - check the bean class before creating the inner class + native call
|
||||
if (bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware
|
||||
|| bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
doProcess(bean);
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
doProcess(bean);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private void doProcess(Object bean) {
|
||||
if (bean instanceof ResourceLoaderAware) {
|
||||
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
|
||||
}
|
||||
|
|
@ -69,11 +104,9 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
|
|||
if (bean instanceof ApplicationContextAware) {
|
||||
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String name) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue